diff --git a/books/bookvol10.4.pamphlet b/books/bookvol10.4.pamphlet
index 5d563d8..5826491 100644
--- a/books/bookvol10.4.pamphlet
+++ b/books/bookvol10.4.pamphlet
@@ -515,6 +515,10 @@ AlgebraicFunction(R, F): Exports == Implementation where
 @
 <<AF.dotabb>>=
 "AF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=AF"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"ACF" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACF"]
+"AF" -> "FS"
+"AF" -> "ACF"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1896,6 +1900,8 @@ AlgFactor(UP): Exports == Implementation where
 @
 <<ALGFACT.dotabb>>=
 "ALGFACT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ALGFACT"]
+"ACF" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACF"]
+"ALGFACT" -> "ACF"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -5359,6 +5365,197 @@ CharacteristicPolynomialPackage(R:CommutativeRing):C == T where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package IBACHIN ChineseRemainderToolsForIntegralBases}
+\pagehead{ChineseRemainderToolsForIntegralBases}{IBACHIN}
+\pagepic{ps/v104chineseremaindertoolsforintegralbases.ps}{IBACHIN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package IBACHIN ChineseRemainderToolsForIntegralBases>>=
+)abbrev package IBACHIN ChineseRemainderToolsForIntegralBases
+++ Author: Clifton Williamson
+++ Date Created: 9 August 1993
+++ Date Last Updated: 3 December 1993
+++ Basic Operations: chineseRemainder, factorList
+++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description:
+
+ChineseRemainderToolsForIntegralBases(K,R,UP): Exports == Implementation where
+  K  : FiniteFieldCategory
+  R  : UnivariatePolynomialCategory K
+  UP : UnivariatePolynomialCategory R
+
+  DDFACT ==> DistinctDegreeFactorize
+  I      ==> Integer
+  L      ==> List
+  L2     ==> ListFunctions2
+  Mat    ==> Matrix R
+  NNI    ==> NonNegativeInteger
+  PI     ==> PositiveInteger
+  Q      ==> Fraction R
+  SAE    ==> SimpleAlgebraicExtension
+  SUP    ==> SparseUnivariatePolynomial
+  SUP2   ==> SparseUnivariatePolynomialFunctions2
+  Result ==> Record(basis: Mat, basisDen: R, basisInv: Mat)
+
+  Exports ==> with
+    factorList: (K,NNI,NNI,NNI) -> L SUP K
+	++ factorList(k,n,m,j) \undocumented
+
+    listConjugateBases: (Result,NNI,NNI) -> List Result
+      ++ listConjugateBases(bas,q,n) returns the list
+      ++ \spad{[bas,bas^Frob,bas^(Frob^2),...bas^(Frob^(n-1))]}, where
+      ++ \spad{Frob} raises the coefficients of all polynomials
+      ++ appearing in the basis \spad{bas} to the \spad{q}th power.
+
+    chineseRemainder: (List UP, List Result, NNI) -> Result
+	++ chineseRemainder(lu,lr,n) \undocumented
+
+  Implementation ==> add
+    import ModularHermitianRowReduction(R)
+    import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+    applyFrobToMatrix: (Matrix R,NNI) -> Matrix R
+    applyFrobToMatrix(mat,q) ==
+      -- raises the coefficients of the polynomial entries of 'mat'
+      -- to the qth power
+      m := nrows mat; n := ncols mat
+      ans : Matrix R := new(m,n,0)
+      for i in 1..m repeat for j in 1..n repeat
+        qsetelt_!(ans,i,j,map(#1 ** q,qelt(mat,i,j)))
+      ans
+
+    listConjugateBases(bas,q,n) ==
+      outList : List Result := list bas
+      b := bas.basis; bInv := bas.basisInv; bDen := bas.basisDen
+      for i in 1..(n-1) repeat
+        b := applyFrobToMatrix(b,q)
+        bInv := applyFrobToMatrix(bInv,q)
+        bDen := map(#1 ** q,bDen)
+        newBasis : Result := [b,bDen,bInv]
+        outList := concat(newBasis,outList)
+      reverse_! outList
+
+    factorList(a,q,n,k) ==
+      coef : SUP K := monomial(a,0); xx : SUP K := monomial(1,1)
+      outList : L SUP K := list((xx - coef)**k)
+      for i in 1..(n-1) repeat
+        coef := coef ** q
+        outList := concat((xx - coef)**k,outList)
+      reverse_! outList
+
+    basisInfoToPolys: (Mat,R,R) -> L UP
+    basisInfoToPolys(mat,lcm,den) ==
+      n := nrows(mat) :: I; n1 := n - 1
+      outList : L UP := empty()
+      for i in 1..n repeat
+        pp : UP := 0
+        for j in 0..n1 repeat
+          pp := pp + monomial((lcm quo den) * qelt(mat,i,j+1),j)
+        outList := concat(pp,outList)
+      reverse_! outList
+
+    basesToPolyLists: (L Result,R) -> L L UP
+    basesToPolyLists(basisList,lcm) ==
+      [basisInfoToPolys(b.basis,lcm,b.basisDen) for b in basisList]
+
+    OUT ==> OutputForm
+
+    approximateExtendedEuclidean: (UP,UP,R,NNI) -> Record(coef1:UP,coef2:UP)
+    approximateExtendedEuclidean(f,g,p,n) ==
+      -- f and g are monic and relatively prime (mod p)
+      -- function returns [coef1,coef2] such that
+      -- coef1 * f + coef2 * g = 1 (mod p^n)
+      sae := SAE(K,R,p)
+      fSUP : SUP R := makeSUP f; gSUP : SUP R := makeSUP g
+      fBar : SUP sae := map(convert(#1)@sae,fSUP)$SUP2(R,sae)
+      gBar : SUP sae := map(convert(#1)@sae,gSUP)$SUP2(R,sae)
+      ee := extendedEuclidean(fBar,gBar)
+--      not one?(ee.generator) =>
+      not (ee.generator = 1) =>
+        error "polynomials aren't relatively prime"
+      ss1 := ee.coef1; tt1 := ee.coef2
+      s1 : SUP R := map(convert(#1)@R,ss1)$SUP2(sae,R); s := s1
+      t1 : SUP R := map(convert(#1)@R,tt1)$SUP2(sae,R); t := t1
+      pPower := p
+      for i in 2..n repeat
+        num := 1 - s * fSUP - t * gSUP
+        rhs := (num exquo pPower) :: SUP R
+        sigma := map(#1 rem p,s1 * rhs); tau := map(#1 rem p,t1 * rhs)
+        s := s + pPower * sigma; t := t + pPower * tau
+        quorem := monicDivide(s,gSUP)
+        pPower := pPower * p
+        s := map(#1 rem pPower,quorem.remainder)
+        t := map(#1 rem pPower,t + fSUP * (quorem.quotient))
+      [unmakeSUP s,unmakeSUP t]
+
+    --mapChineseToList: (L SUP Q,L SUP Q,I) -> L SUP Q
+    --mapChineseToList(list,polyList,i) ==
+    mapChineseToList: (L UP,L UP,I,R) -> L UP
+    mapChineseToList(list,polyList,i,den) ==
+      -- 'polyList' consists of MONIC polynomials
+      -- computes a polynomial p such that p = pp (modulo polyList[i])
+      -- and p = 0 (modulo polyList[j]) for j ~= i for each 'pp' in 'list'
+      -- create polynomials
+      q : UP := 1
+      for j in 1..(i-1) repeat
+        q := q * first polyList
+        polyList := rest polyList
+      p := first polyList
+      polyList := rest polyList
+      for j in (i+1).. while not empty? polyList repeat
+        q := q * first polyList
+        polyList := rest polyList
+      --p := map((numer(#1) rem den)/1, p)
+      --q := map((numer(#1) rem den)/1, q)
+      -- 'den' is a power of an irreducible polynomial
+      --!! make this computation more efficient!!
+      factoredDen := factor(den)$DDFACT(K,R)
+      prime := nthFactor(factoredDen,1)
+      n := nthExponent(factoredDen,1) :: NNI
+      invPoly := approximateExtendedEuclidean(q,p,prime,n).coef1
+      -- monicDivide may be inefficient?
+      [monicDivide(pp * invPoly * q,p * q).remainder for pp in list]
+
+    polyListToMatrix: (L UP,NNI) -> Mat
+    polyListToMatrix(polyList,n) ==
+      mat : Mat := new(n,n,0)
+      for i in 1..n for poly in polyList repeat
+        while not zero? poly repeat
+          mat(i,degree(poly) + 1) := leadingCoefficient poly
+          poly := reductum poly
+      mat
+
+    chineseRemainder(factors,factorBases,n) ==
+      denLCM : R := reduce("lcm",[base.basisDen for base in factorBases])
+      denLCM = 1 => [scalarMatrix(n,1),1,scalarMatrix(n,1)]
+      -- compute local basis polynomials with denominators cleared
+      factorBasisPolyLists := basesToPolyLists(factorBases,denLCM)
+      -- use Chinese remainder to compute basis polynomials w/o denominators
+      basisPolyLists : L L UP := empty()
+      for i in 1.. for pList in factorBasisPolyLists repeat
+        polyList := mapChineseToList(pList,factors,i,denLCM)
+        basisPolyLists := concat(polyList,basisPolyLists)
+      basisPolys := concat reverse_! basisPolyLists
+      mat := squareTop rowEchelon(polyListToMatrix(basisPolys,n),denLCM)
+      matInv := UpTriBddDenomInv(mat,denLCM)
+      [mat,denLCM,matInv]
+
+@
+<<IBACHIN.dotabb>>=
+"IBACHIN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=IBACHIN"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"IBACHIN" -> "MONOGEN"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package CVMP CoerceVectorMatrixPackage}
 \pagehead{CoerceVectorMatrixPackage}{CVMP}
 \pagepic{ps/v104coercevectormatrixpackage.ps}{CVMP}{1.00}
@@ -6327,6 +6524,67 @@ CommonOperators(): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package COMMUPC CommuteUnivariatePolynomialCategory}
+\pagehead{CommuteUnivariatePolynomialCategory}{COMMUPC}
+\pagepic{ps/v104commuteunivariatepolynomialcategory.ps}{COMMUPC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package COMMUPC CommuteUnivariatePolynomialCategory>>=
+)abbrev package COMMUPC CommuteUnivariatePolynomialCategory
+++ Author: Manuel Bronstein
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A package for swapping the order of two variables in a tower of two
+++ UnivariatePolynomialCategory extensions.
+
+CommuteUnivariatePolynomialCategory(R, UP, UPUP): Exports == Impl where
+  R   : Ring
+  UP  : UnivariatePolynomialCategory R
+  UPUP: UnivariatePolynomialCategory UP
+
+  N ==> NonNegativeInteger
+
+  Exports ==> with
+    swap: UPUP -> UPUP
+      ++ swap(p(x,y)) returns p(y,x).
+
+  Impl ==> add
+    makePoly: (UP, N) -> UPUP
+
+-- converts P(x,y) to P(y,x)
+    swap poly ==
+      ans:UPUP := 0
+      while poly ^= 0 repeat
+        ans  := ans + makePoly(leadingCoefficient poly, degree poly)
+        poly := reductum poly
+      ans
+
+    makePoly(poly, d) ==
+      ans:UPUP := 0
+      while poly ^= 0 repeat
+        ans  := ans +
+             monomial(monomial(leadingCoefficient poly, d), degree poly)
+        poly := reductum poly
+      ans
+
+@
+<<COMMUPC.dotabb>>=
+"COMMUPC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=COMMUPC"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"COMMUPC" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package COMPFACT ComplexFactorization}
 \pagehead{ComplexFactorization}{COMPFACT}
 \pagepic{ps/v104complexfactorization.ps}{COMPFACT}{1.00}
@@ -8737,7 +8995,6 @@ The smallest is
 
 See Also:
 o )show CycleIndicators
-o $AXIOM/doc/src/algebra/cycles.spad.dvi
 
 @
 \pagehead{CycleIndicators}{CYCLES}
@@ -16854,10 +17111,6 @@ EvaluateCycleIndicators(F):T==C where
 \begin{tabular}{lllll}
 \end{tabular}
 
-<<ESCONT.dotabb>>=
-"ESCONT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ESCONT"]
-
-@
 <<package ESCONT ExpertSystemContinuityPackage>>=
 )abbrev package ESCONT ExpertSystemContinuityPackage
 ++ Author: Brian Dupee
@@ -17113,6 +17366,8 @@ ExpertSystemContinuityPackage(): E == I where
 @
 <<ESCONT.dotabb>>=
 "ESCONT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ESCONT"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"ESCONT" -> "ACFS"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -17173,6 +17428,7 @@ ExpertSystemContinuityPackage1(A:DF,B:DF): E == I where
 @
 <<ESCONT1.dotabb>>=
 "ESCONT1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ESCONT1"]
+"Package" [color="#FF4488"]
 "ESCONT1" -> "Package"
 
 @
@@ -18584,7 +18840,6 @@ The flags for each base are set to "nil" in the object returned by map.
 See Also:
 o )help Factored
 o )show FactoredFunctions2
-o $AXIOM/doc/src/algebra/fr.spad.dvi
 
 @
 \pagehead{FactoredFunctions2}{FR2}
@@ -18818,6 +19073,44 @@ FactoringUtilities(E,OV,R,P) : C == T where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package FORDER FindOrderFinite}
+\pagehead{FindOrderFinite}{FORDER}
+\pagepic{ps/v104findorderfinite.ps}{FORDER}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package FORDER FindOrderFinite>>=
+)abbrev package FORDER FindOrderFinite
+++ Finds the order of a divisor over a finite field
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 11 Jul 1990
+FindOrderFinite(F, UP, UPUP, R): Exports == Implementation where
+  F   : Join(Finite, Field)
+  UP  : UnivariatePolynomialCategory F
+  UPUP: UnivariatePolynomialCategory Fraction UP
+  R   : FunctionFieldCategory(F, UP, UPUP)
+
+  Exports ==> with
+    order: FiniteDivisor(F, UP, UPUP, R) -> NonNegativeInteger
+	++ order(x) \undocumented
+  Implementation ==> add
+    order d ==
+      dd := d := reduce d
+      for i in 1.. repeat
+        principal? dd => return(i::NonNegativeInteger)
+        dd := reduce(d + dd)
+
+@
+<<FORDER.dotabb>>=
+"FORDER" [color="#FF4488",href="bookvol10.4.pdf#nameddest=FORDER"]
+"FFCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FFCAT"]
+"FORDER" -> "FFCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package FAMR2 FiniteAbelianMonoidRingFunctions2}
 \pagehead{FiniteAbelianMonoidRingFunctions2}{FAMR2}
 \pagepic{ps/v104finiteabelianmonoidringfunctions2.ps}{FAMR2}{1.00}
@@ -23459,6 +23752,202 @@ FunctionSpaceIntegration(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package FSPRMELT FunctionSpacePrimitiveElement}
+\pagehead{FunctionSpacePrimitiveElement}{FSPRMELT}
+\pagepic{ps/v104functionspaceprimitiveelement.ps}{FSPRMELT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package FSPRMELT FunctionSpacePrimitiveElement>>=
+)abbrev package FSPRMELT FunctionSpacePrimitiveElement
+++ Computation of primitive elements.
+++ Author: Manuel Bronstein
+++ Date Created: 6 Jun 1990
+++ Date Last Updated: 25 April 1991
+++ Description:
+++   FunctionsSpacePrimitiveElement provides functions to compute
+++   primitive elements in functions spaces;
+++ Keywords: algebraic, extension, primitive.
+FunctionSpacePrimitiveElement(R, F): Exports == Implementation where
+  R: Join(IntegralDomain, OrderedSet, CharacteristicZero)
+  F: FunctionSpace R
+
+  SY  ==> Symbol
+  P   ==> Polynomial F
+  K   ==> Kernel F
+  UP  ==> SparseUnivariatePolynomial F
+  REC ==> Record(primelt:F, poly:List UP, prim:UP)
+
+  Exports ==> with
+    primitiveElement: List F -> Record(primelt:F, poly:List UP, prim:UP)
+      ++ primitiveElement([a1,...,an]) returns \spad{[a, [q1,...,qn], q]}
+      ++ such that then \spad{k(a1,...,an) = k(a)},
+      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+      ++ This operation uses the technique of
+      ++ \spadglossSee{groebner bases}{Groebner basis}.
+    if F has AlgebraicallyClosedField then
+      primitiveElement: (F,F)->Record(primelt:F,pol1:UP,pol2:UP,prim:UP)
+        ++ primitiveElement(a1, a2) returns \spad{[a, q1, q2, q]}
+        ++ such that \spad{k(a1, a2) = k(a)},
+        ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+        ++ The minimal polynomial for a2 may involve a1, but the
+        ++ minimal polynomial for a1 may not involve a2;
+        ++ This operations uses \spadfun{resultant}.
+
+  Implementation ==> add
+    import PrimitiveElement(F)
+    import AlgebraicManipulations(R, F)
+    import PolynomialCategoryLifting(IndexedExponents K,
+                            K, R, SparseMultivariatePolynomial(R, K), P)
+
+    F2P: (F, List SY) -> P
+    K2P: (K, List SY) -> P
+
+    F2P(f, l) == inv(denom(f)::F) * map(K2P(#1, l), #1::F::P, numer f)
+
+    K2P(k, l) ==
+      ((v := symbolIfCan k) case SY) and member?(v::SY, l) => v::SY::P
+      k::F::P
+
+    primitiveElement l ==
+      u    := string(uu := new()$SY)
+      vars := [concat(u, string i)::SY for i in 1..#l]
+      vv   := [kernel(v)$K :: F for v in vars]
+      kers := [retract(a)@K for a in l]
+      pols := [F2P(subst(ratDenom((minPoly k) v, kers), kers, vv), vars)
+                                              for k in kers for v in vv]
+      rec := primitiveElement(pols, vars, uu)
+      [+/[c * a for c in rec.coef for a in l], rec.poly, rec.prim]
+
+    if F has AlgebraicallyClosedField then
+      import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+                            K, R, SparseMultivariatePolynomial(R, K), F)
+
+      F2UP: (UP, K, UP) -> UP
+      getpoly: (UP, F) -> UP
+
+      F2UP(p, k, q) ==
+        ans:UP := 0
+        while not zero? p repeat
+          f   := univariate(leadingCoefficient p, k)
+          ans := ans + ((numer f) q)
+                       * monomial(inv(retract(denom f)@F), degree p)
+          p   := reductum p
+        ans
+
+      primitiveElement(a1, a2) ==
+        a   := (aa := new()$SY)::F
+        b   := (bb := new()$SY)::F
+        l   := [aa, bb]$List(SY)
+        p1  := minPoly(k1 := retract(a1)@K)
+        p2  := map(subst(ratDenom(#1, [k1]), [k1], [a]),
+                                                 minPoly(retract(a2)@K))
+        rec := primitiveElement(F2P(p1 a, l), aa, F2P(p2 b, l), bb)
+        w   := rec.coef1 * a1 + rec.coef2 * a2
+        g   := rootOf(rec.prim)
+        zero?(rec.coef1) =>
+          c2g := inv(rec.coef2 :: F) * g
+          r := gcd(p1, univariate(p2 c2g, retract(a)@K, p1))
+          q := getpoly(r, g)
+          [w, q, rec.coef2 * monomial(1, 1)$UP, rec.prim]
+        ic1 := inv(rec.coef1 :: F)
+        gg  := (ic1 * g)::UP - monomial(rec.coef2 * ic1, 1)$UP
+        kg  := retract(g)@K
+        r   := gcd(p1 gg, F2UP(p2, retract(a)@K, gg))
+        q   := getpoly(r, g)
+        [w, monomial(ic1, 1)$UP - rec.coef2 * ic1 * q, q, rec.prim]
+
+      getpoly(r, g) ==
+--        one? degree r =>
+        (degree r = 1) =>
+          k := retract(g)@K
+          univariate(-coefficient(r,0)/leadingCoefficient r,k,minPoly k)
+        error "GCD not of degree 1"
+
+@
+<<FSPRMELT.dotabb>>=
+"FSPRMELT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=FSPRMELT"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"FSPRMELT" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package FSRED FunctionSpaceReduce}
+\pagehead{FunctionSpaceReduce}{FSRED}
+\pagepic{ps/v104functionspacereduce.ps}{FSRED}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package FSRED FunctionSpaceReduce>>=
+)abbrev package FSRED FunctionSpaceReduce
+++ Reduction from a function space to the rational numbers
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 11 Jul 1990
+++ Description:
+++ This package provides function which replaces transcendental kernels
+++ in a function space by random integers. The correspondence between
+++ the kernels and the integers is fixed between calls to new().
+++ Keywords: function, space, redcution.
+FunctionSpaceReduce(R, F): Exports == Implementation where
+  R: Join(OrderedSet, IntegralDomain, RetractableTo Integer)
+  F: FunctionSpace R
+
+  Z   ==> Integer
+  Q   ==> Fraction Integer
+  UP  ==> SparseUnivariatePolynomial Q
+  K   ==> Kernel F
+  ALGOP  ==> "%alg"
+
+  Exports ==> with
+    bringDown: F -> Q
+	++ bringDown(f) \undocumented
+    bringDown: (F, K) -> UP
+	++ bringDown(f,k) \undocumented
+    newReduc : () -> Void
+	++ newReduc() \undocumented
+
+  Implementation ==> add
+    import SparseUnivariatePolynomialFunctions2(F, Q)
+    import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+                         K, R, SparseMultivariatePolynomial(R, K), F)
+
+    K2Z : K -> F
+
+    redmap := table()$AssociationList(K, Z)
+
+    newReduc() ==
+      for k in keys redmap repeat remove_!(k, redmap)
+      void
+
+    bringDown(f, k) ==
+      ff := univariate(f, k)
+      (bc := extendedEuclidean(map(bringDown, denom ff),
+                m := map(bringDown, minPoly k), 1)) case "failed" =>
+                     error "denominator is 0"
+      (map(bringDown, numer ff) * bc.coef1) rem m
+
+    bringDown f ==
+      retract(eval(f, lk := kernels f, [K2Z k for k in lk]))@Q
+
+    K2Z k ==
+      has?(operator k, ALGOP) => error "Cannot reduce constant field"
+      (u := search(k, redmap)) case "failed" =>
+                                      setelt(redmap, k, random()$Z)::F
+      u::Z::F
+
+@
+<<FSRED.dotabb>>=
+"FSRED" [color="#FF4488",href="bookvol10.4.pdf#nameddest=FSRED"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"FSRED" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package SUMFS FunctionSpaceSum}
 \pagehead{FunctionSpaceSum}{SUMFS}
 \pagepic{ps/v104functionspacesum.ps}{SUMFS}{1.00}
@@ -28216,6 +28705,96 @@ GraphicsDefaults(): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package GRAY GrayCode}
+\pagehead{GrayCode}{GRAY}
+\pagepic{ps/v104graycode.ps}{GRAY}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package GRAY GrayCode>>=
+)abbrev package GRAY GrayCode
+++ Authors: Johannes Grabmeier, Oswald Gschnitzer
+++ Date Created: 7 August 1989
+++ Date Last Updated: 23 August 1990
+++ Basic Operations: nextSubsetGray
+++ Related Constructors: Permanent
+++ Also See: SymmetricGroupCombinatoric Functions
+++ AMS Classifications:
+++ Keywords: gray code, subsets of finite sets 
+++ References:
+++  Henryk Minc: Evaluation of Permanents,
+++    Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
+++  Nijenhuis and Wilf : Combinatorical Algorithms, Academic
+++    Press, New York 1978.
+++   S.G.Williamson, Combinatorics for Computer Science,
+++    Computer Science Press, 1985.
+++ Description:
+++  GrayCode provides a function for efficiently running
+++  through all subsets of a finite set, only changing one element
+++  by another one.
+GrayCode: public == private where
+ 
+  PI ==> PositiveInteger
+  I  ==> Integer
+  V  ==> Vector
+ 
+  public ==> with
+ 
+    nextSubsetGray: (V V I,PI) -> V V I
+      ++ nextSubsetGray(ww,n) returns a vector {\em vv} whose components
+      ++ have the following meanings:\begin{items}
+      ++ \item {\em vv.1}: a vector of length n whose entries are 0 or 1. This
+      ++    can be interpreted as a code for a subset of the set 1,...,n;
+      ++    {\em vv.1} differs from {\em ww.1} by exactly one entry;
+      ++ \item {\em vv.2.1} is the number of the entry of {\em vv.1} which
+      ++    will be changed next time;
+      ++ \item {\em vv.2.1 = n+1} means that {\em vv.1} is the last subset;
+      ++    trying to compute nextSubsetGray(vv) if {\em vv.2.1 = n+1}
+      ++    will produce an error!
+      ++ \end{items}
+      ++ The other components of {\em vv.2} are needed to compute
+      ++ nextSubsetGray efficiently.
+      ++ Note: this is an implementation of [Williamson, Topic II, 3.54,
+      ++ p. 112] for the special case {\em r1 = r2 = ... = rn = 2};
+      ++ Note: nextSubsetGray produces a side-effect, i.e.
+      ++ {\em nextSubsetGray(vv)} and {\em vv := nextSubsetGray(vv)}
+      ++ will have the same effect.
+ 
+    firstSubsetGray: PI -> V V I
+      ++ firstSubsetGray(n) creates the first vector {\em ww} to start a
+      ++ loop using {\em nextSubsetGray(ww,n)}
+ 
+  private ==> add
+ 
+    firstSubsetGray(n : PI) ==
+      vv : V V I := new(2,[])
+      vv.1 := new(n,0) : V I
+      vv.2 := new(n+1,1) : V I
+      for i in 1..(n+1) repeat
+        vv.2.i := i
+      vv
+ 
+    nextSubsetGray(vv : V V I,n : PI) ==
+      subs : V I := vv.1    -- subset
+      lab : V I := vv.2     -- labels
+      c : I := lab(1)    -- element which is to be changed next
+      lab(1):= 1
+      if subs.c = 0 then subs.c := 1
+      else subs.c := 0
+      lab.c := lab(c+1)
+      lab(c+1) := c+1
+      vv
+
+@
+<<GRAY.dotabb>>=
+"GRAY" [color="#FF4488",href="bookvol10.4.pdf#nameddest=GRAY"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"GRAY" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package GBF GroebnerFactorizationPackage}
 <<GroebnerFactorizationPackage.input>>=
 -- groebf.spad.pamphlet GroebnerFactorizationPackage.input
@@ -35002,6 +35581,8 @@ InnerAlgFactor(F, UP, AlExt, AlPol): Exports == Implementation where
 @
 <<IALGFACT.dotabb>>=
 "IALGFACT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=IALGFACT"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"IALGFACT" -> "MONOGEN"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -37764,7 +38345,6 @@ solveLinearlyOverQ.
 
 See Also:
 o )show IntegerLinearDependence
-o $AXIOM/doc/src/algebra/lindep.spad.dvi
 
 @
 \pagehead{IntegerLinearDependence}{ZLINDEP}
@@ -39445,6 +40025,111 @@ IntegralBasisTools(R,UP,F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package IBPTOOLS IntegralBasisPolynomialTools}
+\pagehead{IntegralBasisPolynomialTools}{IBPTOOLS}
+\pagepic{ps/v104integralbasispolynomialtools.ps}{IBPTOOLS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package IBPTOOLS IntegralBasisPolynomialTools>>=
+)abbrev package IBPTOOLS IntegralBasisPolynomialTools
+++ Author: Clifton Williamson
+++ Date Created: 13 August 1993
+++ Date Last Updated: 17 August 1993
+++ Basic Operations: mapUnivariate, mapBivariate
+++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description:  IntegralBasisPolynomialTools provides functions for
+++   mapping functions on the coefficients of univariate and bivariate
+++   polynomials.
+
+IntegralBasisPolynomialTools(K,R,UP,L): Exports == Implementation where
+  K  : Ring
+  R  : UnivariatePolynomialCategory K
+  UP : UnivariatePolynomialCategory R
+  L  : Ring
+
+  MAT ==> Matrix
+  SUP ==> SparseUnivariatePolynomial
+
+  Exports ==> with
+    mapUnivariate: (L -> K,SUP L) -> R
+      ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
+      ++ coefficients of \spad{p(x)}.
+
+    mapUnivariate: (K -> L,R) -> SUP L
+      ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
+      ++ coefficients of \spad{p(x)}.
+
+    mapUnivariateIfCan: (L -> Union(K,"failed"),SUP L) -> Union(R,"failed")
+      ++ mapUnivariateIfCan(f,p(x)) applies the function \spad{f} to the
+      ++ coefficients of \spad{p(x)}, if possible, and returns
+      ++ \spad{"failed"} otherwise.
+
+    mapMatrixIfCan: (L -> Union(K,"failed"),MAT SUP L) -> Union(MAT R,"failed")
+      ++ mapMatrixIfCan(f,mat) applies the function \spad{f} to the
+      ++ coefficients of the entries of \spad{mat} if possible, and returns
+      ++ \spad{"failed"} otherwise.
+
+    mapBivariate: (K -> L,UP) -> SUP SUP L
+      ++ mapBivariate(f,p(x,y)) applies the function \spad{f} to the
+      ++ coefficients of \spad{p(x,y)}.
+
+  Implementation ==> add
+
+    mapUnivariate(f:L -> K,poly:SUP L) ==
+      ans : R := 0
+      while not zero? poly repeat
+        ans := ans + monomial(f leadingCoefficient poly,degree poly)
+        poly := reductum poly
+      ans
+
+    mapUnivariate(f:K -> L,poly:R) ==
+      ans : SUP L := 0
+      while not zero? poly repeat
+        ans := ans + monomial(f leadingCoefficient poly,degree poly)
+        poly := reductum poly
+      ans
+
+    mapUnivariateIfCan(f,poly) ==
+      ans : R := 0
+      while not zero? poly repeat
+        (lc := f leadingCoefficient poly) case "failed" => return "failed"
+        ans := ans + monomial(lc :: K,degree poly)
+        poly := reductum poly
+      ans
+
+    mapMatrixIfCan(f,mat) ==
+      m := nrows mat; n := ncols mat
+      matOut : MAT R := new(m,n,0)
+      for i in 1..m repeat for j in 1..n repeat
+        (poly := mapUnivariateIfCan(f,qelt(mat,i,j))) case "failed" =>
+          return "failed"
+        qsetelt_!(matOut,i,j,poly :: R)
+      matOut
+
+    mapBivariate(f,poly) ==
+      ans : SUP SUP L := 0
+      while not zero? poly repeat
+        ans :=
+          ans + monomial(mapUnivariate(f,leadingCoefficient poly),degree poly)
+        poly := reductum poly
+      ans
+
+@
+<<IBPTOOLS.dotabb>>=
+"IBPTOOLS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=IBPTOOLS"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"IBPTOOLS" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package IR2 IntegrationResultFunctions2}
 \pagehead{IntegrationResultFunctions2}{IR2}
 \pagepic{ps/v104integrationresultfunctions2.ps}{IR2}{1.00}
@@ -47606,6 +48291,110 @@ MPolyCatRationalFunctionFactorizer(E,OV,R,PRF) : C == T
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package MPC2 MPolyCatFunctions2}
+\pagehead{MPolyCatFunctions2}{MPC2}
+\pagepic{ps/v104mpolycatfunctions2.ps}{MPC2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package MPC2 MPolyCatFunctions2>>=
+)abbrev package MPC2 MPolyCatFunctions2
+++ Utilities for MPolyCat
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 28 March 1990  (PG)
+MPolyCatFunctions2(VarSet,E1,E2,R,S,PR,PS) : public == private where
+ 
+  VarSet : OrderedSet
+  E1     : OrderedAbelianMonoidSup
+  E2     : OrderedAbelianMonoidSup
+  R      : Ring
+  S      : Ring
+  PR     : PolynomialCategory(R,E1,VarSet)
+  PS     : PolynomialCategory(S,E2,VarSet)
+  SUPR   ==> SparseUnivariatePolynomial PR
+  SUPS   ==> SparseUnivariatePolynomial PS
+ 
+  public == with
+    map:     (R -> S,PR) -> PS
+	++ map(f,p) \undocumented	
+    reshape: (List S, PR) -> PS
+	++ reshape(l,p) \undocumented
+ 
+  private == add
+ 
+    supMap:  (R -> S, SUPR) -> SUPS
+ 
+    supMap(fn : R -> S, supr : SUPR): SUPS ==
+      supr = 0 => monomial(fn(0$R) :: PS,0)$SUPS
+      c : PS := map(fn,leadingCoefficient supr)$%
+      monomial(c,degree supr)$SUPS + supMap(fn, reductum supr)
+ 
+    map(fn : R -> S, pr : PR): PS ==
+      varu : Union(VarSet,"failed") := mainVariable pr
+      varu case "failed" =>  -- have a constant
+        fn(retract pr) :: PS
+      var : VarSet := varu :: VarSet
+      supr : SUPR := univariate(pr,var)$PR
+      multivariate(supMap(fn,supr),var)$PS
+
+@
+<<MPC2.dotabb>>=
+"MPC2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=MPC2"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"MPC2" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package MPC3 MPolyCatFunctions3}
+\pagehead{MPolyCatFunctions3}{MPC3}
+\pagepic{ps/v104mpolycatfunctions3.ps}{MPC3}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package MPC3 MPolyCatFunctions3>>=
+)abbrev package MPC3 MPolyCatFunctions3
+++ Description:
+++ This package \undocumented
+MPolyCatFunctions3(Vars1,Vars2,E1,E2,R,PR1,PR2): C == T where
+  E1   : OrderedAbelianMonoidSup
+  E2   : OrderedAbelianMonoidSup
+  Vars1: OrderedSet
+  Vars2: OrderedSet
+  R    : Ring
+  PR1  : PolynomialCategory(R,E1,Vars1)
+  PR2  : PolynomialCategory(R,E2,Vars2)
+ 
+  C ==> with
+    map: (Vars1 -> Vars2, PR1) -> PR2
+	++ map(f,x) \undocumented
+ 
+  T ==> add
+ 
+    map(f:Vars1 -> Vars2, p:PR1):PR2 ==
+      (x1 := mainVariable p) case "failed" =>
+        c:R:=(retract p)
+        c::PR2
+      up := univariate(p, x1::Vars1)
+      x2 := f(x1::Vars1)
+      ans:PR2 := 0
+      while up ^= 0 repeat
+        ans := ans + monomial(map(f,leadingCoefficient up),x2,degree up)
+        up  := reductum up
+      ans
+
+@
+<<MPC3.dotabb>>=
+"MPC3" [color="#FF4488",href="bookvol10.4.pdf#nameddest=MPC3"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"MPC3" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package MRATFAC MRationalFactorize}
 \pagehead{MRationalFactorize}{MRATFAC}
 \pagepic{ps/v104mrationalfactorize.ps}{MRATFAC}{1.00}
@@ -47669,6 +48458,8 @@ MRationalFactorize(E,OV,R,P) : C == T
 @
 <<MRATFAC.dotabb>>=
 "MRATFAC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=MRATFAC"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"MRATFAC" -> "PFECAT"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -52774,6 +53565,8 @@ NagPolynomialRootsPackage(): Exports == Implementation where
 @
 <<NAGC02.dotabb>>=
 "NAGC02" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NAGC02"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"NAGC02" -> "ALIST"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -52908,6 +53701,8 @@ NagRootFindingPackage(): Exports == Implementation where
 @
 <<NAGC05.dotabb>>=
 "NAGC05" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NAGC05"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"NAGC05" -> "ALIST"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -53205,6 +54000,8 @@ NagSeriesSummationPackage(): Exports == Implementation where
 @
 <<NAGC06.dotabb>>=
 "NAGC06" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NAGC06"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"NAGC06" -> "ALIST"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -53997,6 +54794,8 @@ NormInMonogenicAlgebra(R, PolR, E, PolE): Exports == Implementation where
 @
 <<NORMMA.dotabb>>=
 "NORMMA" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NORMMA"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"NORMMA" -> "MONOGEN"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -56102,12 +56901,6 @@ NumericComplexEigenPackage(Par) : C == T
 "NCEP" -> "COMPCAT"
 
 @
-<<NCEP.dotabb>>=
-"NCEP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NCEP"]
-"COMPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=COMPCAT"]
-"NCEP" -> "COMPCAT"
-
-@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package NCNTFRAC NumericContinuedFraction}
 \pagehead{NumericContinuedFraction}{NCNTFRAC}
@@ -56559,6 +57352,8 @@ OneDimensionalArrayFunctions2(A, B): Exports == Implementation where
 @
 <<ARRAY12.dotabb>>=
 "ARRAY12" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ARRAY12"]
+"A1AGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=A1AGG"]
+"ARRAY12" -> "A1AGG"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57017,6 +57812,1636 @@ OutputPackage: with
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter P}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PADEPAC PadeApproximantPackage}
+\pagehead{PadeApproximantPackage}{PADEPAC}
+\pagepic{ps/v104padeapproximantpackage.ps}{PADEPAC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PADEPAC PadeApproximantPackage>>=
+)abbrev package PADEPAC PadeApproximantPackage
+++ This package computes reliable Pad&ea. approximants using
+++ a generalized Viskovatov continued fraction algorithm.
+++ Authors: Trager,Burge, Hassner & Watt.
+++ Date Created: April 1987
+++ Date Last Updated: 12 April 1990
+++ Keywords: Pade, series
+++ Examples:
+++ References:
+++   "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
+
+PadeApproximantPackage(R: Field, x:Symbol, pt:R): Exports == Implementation where
+   PS ==> UnivariateTaylorSeries(R,x,pt)
+   UP ==> UnivariatePolynomial(x,R)
+   QF ==> Fraction UP
+   CF  ==> ContinuedFraction UP
+   NNI ==> NonNegativeInteger
+   Exports ==> with
+     pade:   (NNI,NNI,PS,PS) -> Union(QF,"failed")
+      ++ pade(nd,dd,ns,ds) computes the approximant as a quotient of polynomials
+      ++ (if it exists) for arguments
+      ++ nd (numerator degree of approximant),
+      ++ dd (denominator degree of approximant),
+      ++ ns (numerator series of function), and
+      ++ ds (denominator series of function).
+     pade:   (NNI,NNI,PS) -> Union(QF,"failed")
+      ++ pade(nd,dd,s)
+      ++ computes the quotient of polynomials
+      ++ (if it exists) with numerator degree at
+      ++ most nd and denominator degree at most dd
+      ++ which matches the series s to order \spad{nd + dd}.
+
+   Implementation ==> add
+     n,m : NNI
+     u,v : PS
+     pa := PadeApproximants(R,PS,UP)
+     pade(n,m,u,v) ==
+       ans:=pade(n,m,u,v)$pa
+       ans case "failed" => ans
+       pt = 0 => ans
+       num := numer(ans::QF)
+       den := denom(ans::QF)
+       xpt : UP := monomial(1,1)-monomial(pt,0)
+       num := num(xpt)
+       den := den(xpt)
+       num/den
+     pade(n,m,u) == pade(n,m,u,1)
+
+@
+<<PADEPAC.dotabb>>=
+"PADEPAC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PADEPAC"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PADEPAC" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PADE PadeApproximants}
+\pagehead{PadeApproximants}{PADE}
+\pagepic{ps/v104padeapproximants.ps}{PADE}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PADE PadeApproximants>>=
+)abbrev package PADE PadeApproximants
+++ This package computes reliable Pad&ea. approximants using
+++ a generalized Viskovatov continued fraction algorithm.
+++ Authors: Burge, Hassner & Watt.
+++ Date Created: April 1987
+++ Date Last Updated: 12 April 1990
+++ Keywords: Pade, series
+++ Examples:
+++ References:
+++   "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
+PadeApproximants(R,PS,UP): Exports == Implementation where
+  R:  Field -- IntegralDomain
+  PS: UnivariateTaylorSeriesCategory R
+  UP: UnivariatePolynomialCategory R
+ 
+  NNI ==> NonNegativeInteger
+  QF  ==> Fraction UP
+  CF  ==> ContinuedFraction UP
+ 
+  Exports ==> with
+    pade:   (NNI,NNI,PS,PS) -> Union(QF,"failed")
+      ++ pade(nd,dd,ns,ds)
+      ++ computes the approximant as a quotient of polynomials
+      ++ (if it exists) for arguments
+      ++ nd (numerator degree of approximant),
+      ++ dd (denominator degree of approximant),
+      ++ ns (numerator series of function), and
+      ++ ds (denominator series of function).
+    padecf: (NNI,NNI,PS,PS) -> Union(CF, "failed")
+      ++ padecf(nd,dd,ns,ds)
+      ++ computes the approximant as a continued fraction of
+      ++ polynomials (if it exists) for arguments
+      ++ nd (numerator degree of approximant),
+      ++ dd (denominator degree of approximant),
+      ++ ns (numerator series of function), and
+      ++ ds (denominator series of function).
+ 
+  Implementation ==> add
+    -- The approximant is represented as
+    --   p0 + x**a1/(p1 + x**a2/(...))
+ 
+    PadeRep ==> Record(ais: List UP, degs: List NNI) -- #ais= #degs
+    PadeU   ==> Union(PadeRep, "failed")             -- #ais= #degs+1
+ 
+    constInner(up:UP):PadeU == [[up], []]
+ 
+    truncPoly(p:UP,n:NNI):UP ==
+      while n < degree p repeat p := reductum p
+      p
+ 
+    truncSeries(s:PS,n:NNI):UP ==
+      p: UP := 0
+      for i in 0..n repeat p := p + monomial(coefficient(s,i),i)
+      p
+ 
+    -- Assumes s starts with a<n>*x**n + ... and divides out x**n.
+    divOutDegree(s:PS,n:NNI):PS ==
+      for i in 1..n repeat s := quoByVar s
+      s
+ 
+    padeNormalize: (NNI,NNI,PS,PS) -> PadeU
+    padeInner:     (NNI,NNI,PS,PS) -> PadeU
+ 
+    pade(l,m,gps,dps) ==
+      (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
+      plist := ad.ais; dlist := ad.degs
+      approx := first(plist) :: QF
+      for d in dlist for p in rest plist repeat
+        approx := p::QF + (monomial(1,d)$UP :: QF)/approx
+      approx
+ 
+    padecf(l,m,gps,dps) ==
+      (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
+      alist := reverse(ad.ais)
+      blist := [monomial(1,d)$UP for d in reverse ad.degs]
+      continuedFraction(first(alist),_
+                          blist::Stream UP,(rest alist) :: Stream UP)
+ 
+    padeNormalize(l,m,gps,dps) ==
+      zero? dps => "failed"
+      zero? gps => constInner 0
+      -- Normalize so numerator or denominator has constant term.
+      ldeg:= min(order dps,order gps)
+      if ldeg > 0 then
+        dps := divOutDegree(dps,ldeg)
+        gps := divOutDegree(gps,ldeg)
+      padeInner(l,m,gps,dps)
+ 
+    padeInner(l, m, gps, dps) ==
+      zero? coefficient(gps,0) and zero? coefficient(dps,0) =>
+        error "Pade' problem not normalized."
+      plist: List UP := nil()
+      alist: List NNI := nil()
+      -- Ensure denom has constant term.
+      if zero? coefficient(dps,0) then
+        -- g/d = 0 + z**0/(d/g)
+        (gps,dps) := (dps,gps)
+        (l,m)     := (m,l)
+        plist := concat(0,plist)
+        alist := concat(0,alist)
+      -- Ensure l >= m, maintaining coef(dps,0)^=0.
+      if l < m then
+        --   (a<n>*x**n + a<n+1>*x**n+1 + ...)/b
+        -- = x**n/b + (a<n> + a<n+1>*x + ...)/b
+        alpha := order gps
+        if alpha > l then return "failed"
+        gps := divOutDegree(gps, alpha)
+        (l,m) := (m,(l-alpha) :: NNI)
+        (gps,dps) := (dps,gps)
+        plist := concat(0,plist)
+        alist := concat(alpha,alist)
+      degbd: NNI := l + m + 1
+      g := truncSeries(gps,degbd)
+      d := truncSeries(dps,degbd)
+      for j in 0.. repeat
+        -- Normalize d so constant coefs cancel. (B&G-M is wrong)
+        d0 := coefficient(d,0)
+        d := (1/d0) * d; g := (1/d0) * g
+        p : UP := 0; s := g
+        if l-m+1 < 0 then error "Internal pade error"
+        degbd := (l-m+1) :: NNI
+        for k in 1..degbd repeat
+          pk := coefficient(s,0)
+          p  := p + monomial(pk,(k-1) :: NNI)
+          s  := s - pk*d
+          s  := (s exquo monomial(1,1)) :: UP
+        plist := concat(p,plist)
+        s = 0 => return [plist,alist]
+        alpha := minimumDegree(s) + degbd
+        alpha > l + m => return [plist,alist]
+        alpha > l     => return "failed"
+        alist := concat(alpha,alist)
+        h := (s exquo monomial(1,minimumDegree s)) :: UP
+        degbd := (l + m - alpha) :: NNI
+        g := truncPoly(d,degbd)
+        d := truncPoly(h,degbd)
+        (l,m) := (m,(l-alpha) :: NNI)
+
+@
+<<PADE.dotabb>>=
+"PADE" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PADE"]
+"UTSCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=UTSCAT"]
+"PADE" -> "UTSCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PWFFINTB PAdicWildFunctionFieldIntegralBasis}
+\pagehead{PAdicWildFunctionFieldIntegralBasis}{PWFFINTB}
+\pagepic{ps/v104padicwildfunctionfieldintegralbasis.ps}{PWFFINTB}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>=
+)abbrev package PWFFINTB PAdicWildFunctionFieldIntegralBasis
+++ Author: Clifton Williamson
+++ Date Created: 5 July 1993
+++ Date Last Updated: 17 August 1993
+++ Basic Operations: integralBasis, localIntegralBasis
+++ Related Domains: WildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description:
+++ In this package K is a finite field, R is a ring of univariate
+++ polynomials over K, and F is a monogenic algebra over R.
+++ We require that F is monogenic, i.e. that \spad{F = K[x,y]/(f(x,y))},
+++ because the integral basis algorithm used will factor the polynomial
+++ \spad{f(x,y)}.  The package provides a function to compute the integral
+++ closure of R in the quotient field of F as well as a function to compute
+++ a "local integral basis" at a specific prime.
+
+PAdicWildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
+  K  : FiniteFieldCategory
+  R  : UnivariatePolynomialCategory K
+  UP : UnivariatePolynomialCategory R
+  F  : MonogenicAlgebra(R,UP)
+
+  I        ==> Integer
+  L        ==> List
+  L2       ==> ListFunctions2
+  Mat      ==> Matrix R
+  NNI      ==> NonNegativeInteger
+  PI       ==> PositiveInteger
+  Q        ==> Fraction R
+  SAE      ==> SimpleAlgebraicExtension
+  SUP      ==> SparseUnivariatePolynomial
+  CDEN     ==> CommonDenominator
+  DDFACT   ==> DistinctDegreeFactorize
+  WFFINTBS ==> WildFunctionFieldIntegralBasis
+  Result   ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
+  IResult  ==> Record(basis: Mat, basisDen: R, basisInv:Mat,discr: R)
+  IBPTOOLS ==> IntegralBasisPolynomialTools
+  IBACHIN  ==> ChineseRemainderToolsForIntegralBases
+  IRREDFFX ==> IrredPolyOverFiniteField
+  GHEN     ==> GeneralHenselPackage
+
+  Exports ==> with
+    integralBasis : () -> Result
+      ++ \spad{integralBasis()} returns a record
+      ++ \spad{[basis,basisDen,basisInv] } containing information regarding
+      ++ the integral closure of R in the quotient field of the framed
+      ++ algebra F.  F is a framed algebra with R-module basis
+      ++ \spad{w1,w2,...,wn}.
+      ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+      ++ the \spad{i}th element of the integral basis is
+      ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+      ++ \spad{i}th row of 'basis' contains the coordinates of the
+      ++ \spad{i}th basis vector.  Similarly, the \spad{i}th row of the
+      ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
+      ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
+      ++ \spad{(bij, i = 1..n, j = 1..n)}, then
+      ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+    localIntegralBasis : R -> Result
+      ++ \spad{integralBasis(p)} returns a record
+      ++ \spad{[basis,basisDen,basisInv] } containing information regarding
+      ++ the local integral closure of R at the prime \spad{p} in the quotient
+      ++ field of the framed algebra F.  F is a framed algebra with R-module
+      ++ basis \spad{w1,w2,...,wn}.
+      ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+      ++ the \spad{i}th element of the local integral basis is
+      ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+      ++ \spad{i}th row of 'basis' contains the coordinates of the
+      ++ \spad{i}th basis vector.  Similarly, the \spad{i}th row of the
+      ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
+      ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
+      ++ \spad{(bij, i = 1..n, j = 1..n)}, then
+      ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+    reducedDiscriminant: UP -> R
+	++ reducedDiscriminant(up) \undocumented
+
+  Implementation ==> add
+    import IntegralBasisTools(R, UP, F)
+    import GeneralHenselPackage(R,UP)
+    import ModularHermitianRowReduction(R)
+    import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+    reducedDiscriminant f ==
+      ff : SUP Q := mapUnivariate(#1 :: Q,f)$IBPTOOLS(R,UP,SUP UP,Q)
+      ee := extendedEuclidean(ff,differentiate ff)
+      cc := concat(coefficients(ee.coef1),coefficients(ee.coef2))
+      cden := splitDenominator(cc)$CDEN(R,Q,L Q)
+      denom := cden.den
+      gg := gcd map(numer,cden.num)$L2(Q,R)
+      (ans := denom exquo gg) case "failed" =>
+        error "PWFFINTB: error in reduced discriminant computation"
+      ans :: R
+
+    compLocalBasis: (UP,R) -> Result
+    compLocalBasis(poly,prime) ==
+      -- compute a local integral basis at 'prime' for k[x,y]/(poly(x,y)).
+      sae := SAE(R,UP,poly)
+      localIntegralBasis(prime)$WFFINTBS(K,R,UP,sae)
+
+    compLocalBasisOverExt: (UP,R,UP,NNI) -> Result
+    compLocalBasisOverExt(poly0,prime0,irrPoly0,k) ==
+      -- poly0 = irrPoly0**k (mod prime0)
+      n := degree poly0; disc0 := discriminant poly0
+      (disc0 exquo prime0) case "failed" =>
+        [scalarMatrix(n,1), 1, scalarMatrix(n,1)]
+      r := degree irrPoly0
+      -- extend scalars:
+      -- construct irreducible polynomial of degree r over K
+      irrPoly := generateIrredPoly(r :: PI)$IRREDFFX(K)
+      -- construct extension of degree r over K
+      E := SAE(K,SUP K,irrPoly)
+      -- lift coefficients to elements of E
+      poly := mapBivariate(#1 :: E,poly0)$IBPTOOLS(K,R,UP,E)
+      redDisc0 := reducedDiscriminant poly0
+      redDisc := mapUnivariate(#1 :: E,redDisc0)$IBPTOOLS(K,R,UP,E)
+      prime := mapUnivariate(#1 :: E,prime0)$IBPTOOLS(K,R,UP,E)
+      sae := SAE(E,SUP E,prime)
+      -- reduction (mod prime) of polynomial of which poly is the kth power
+      redIrrPoly :=
+        pp := mapBivariate(#1 :: E,irrPoly0)$IBPTOOLS(K,R,UP,E)
+        mapUnivariate(reduce,pp)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae)
+      -- factor the reduction
+      factorListSAE := factors factor(redIrrPoly)$DDFACT(sae,SUP sae)
+      -- list the 'primary factors' of the reduction of poly
+      redFactors : List SUP sae := [(f.factor)**k for f in factorListSAE]
+      -- lift these factors to elements of SUP SUP E
+      primaries : List SUP SUP E :=
+        [mapUnivariate(lift,ff)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae) _
+             for ff in redFactors]
+      -- lift the factors to factors modulo a suitable power of 'prime'
+      deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
+      henselInfo := HenselLift(poly,primaries,prime,deg)$GHEN(SUP E,SUP SUP E)
+      henselFactors := henselInfo.plist
+      psi1 := first henselFactors
+      FF := SAE(SUP E,SUP SUP E,psi1)
+      factorIb := localIntegralBasis(prime)$WFFINTBS(E,SUP E,SUP SUP E,FF)
+      bs := listConjugateBases(factorIb,size()$K,r)$IBACHIN(E,SUP E,SUP SUP E)
+      ib := chineseRemainder(henselFactors,bs,n)$IBACHIN(E,SUP E,SUP SUP E)
+      b : Matrix R :=
+        bas := mapMatrixIfCan(retractIfCan,ib.basis)$IBPTOOLS(K,R,UP,E)
+        bas case "failed" => error "retraction of basis failed"
+        bas :: Matrix R
+      bInv : Matrix R :=
+        --bas := mapMatrixIfCan(ric,ib.basisInv)$IBPTOOLS(K,R,UP,E)
+        bas := mapMatrixIfCan(retractIfCan,ib.basisInv)$IBPTOOLS(K,R,UP,E)
+        bas case "failed" => error "retraction of basis inverse failed"
+        bas :: Matrix R
+      bDen : R :=
+        p := mapUnivariateIfCan(retractIfCan,ib.basisDen)$IBPTOOLS(K,R,UP,E)
+        p case "failed" => error "retraction of basis denominator failed"
+        p :: R
+      [b,bDen,bInv]
+
+    padicLocalIntegralBasis: (UP,R,R,R) -> IResult
+    padicLocalIntegralBasis(p,disc,redDisc,prime) ==
+      -- polynomials in x modulo 'prime'
+      sae := SAE(K,R,prime)
+      -- find the factorization of 'p' modulo 'prime' and lift the
+      -- prime powers to elements of UP:
+      -- reduce 'p' modulo 'prime'
+      reducedP := mapUnivariate(reduce,p)$IBPTOOLS(R,UP,SUP UP,sae)
+      -- factor the reduced polynomial
+      factorListSAE := factors factor(reducedP)$DDFACT(sae,SUP sae)
+      -- if only one prime factor, perform usual integral basis computation
+      (# factorListSAE) = 1 =>
+        ib := localIntegralBasis(prime)$WFFINTBS(K,R,UP,F)
+        index := diagonalProduct(ib.basisInv)
+        [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
+      -- list the 'prime factors' of the reduced polynomial
+      redPrimes : List SUP sae :=
+        [f.factor for f in factorListSAE]
+      -- lift these factors to elements of UP
+      primes : List UP :=
+        [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimes]
+      -- list the exponents
+      expons : List NNI := [((f.exponent) :: NNI) for f in factorListSAE]
+      -- list the 'primary factors' of the reduced polynomial
+      redPrimaries : List SUP sae :=
+        [(f.factor) **((f.exponent) :: NNI) for f in factorListSAE]
+      -- lift these factors to elements of UP
+      primaries : List UP :=
+        [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimaries]
+      -- lift the factors to factors modulo a suitable power of 'prime'
+      deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
+      henselInfo := HenselLift(p,primaries,prime,deg)
+      henselFactors := henselInfo.plist
+      -- compute integral bases for the factors
+      factorBases : List Result := empty(); degPrime := degree prime
+      for pp in primes for k in expons for qq in henselFactors repeat
+        base :=
+          degPp := degree pp
+          degPp > 1 and gcd(degPp,degPrime) = 1 =>
+            compLocalBasisOverExt(qq,prime,pp,k)
+          compLocalBasis(qq,prime)
+        factorBases := concat(base,factorBases)
+      factorBases := reverse_! factorBases
+      ib := chineseRemainder(henselFactors,factorBases,rank()$F)$IBACHIN(K,R,UP)
+      index := diagonalProduct(ib.basisInv)
+      [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
+
+    localIntegralBasis prime ==
+      p := definingPolynomial()$F; disc := discriminant p
+      --disc := determinant traceMatrix()$F
+      redDisc := reducedDiscriminant p
+      ib := padicLocalIntegralBasis(p,disc,redDisc,prime)
+      [ib.basis,ib.basisDen,ib.basisInv]
+
+    listSquaredFactors: R -> List R
+    listSquaredFactors px ==
+      -- returns a list of the factors of px which occur with
+      -- exponent > 1
+      ans : List R := empty()
+      factored := factor(px)$DistinctDegreeFactorize(K,R)
+      for f in factors(factored) repeat
+        if f.exponent > 1 then ans := concat(f.factor,ans)
+      ans
+
+    integralBasis() ==
+      p := definingPolynomial()$F; disc := discriminant p; n := rank()$F
+      --traceMat := traceMatrix()$F; n := rank()$F
+      --disc := determinant traceMat        -- discriminant of current order
+      singList := listSquaredFactors disc -- singularities of relative Spec
+      redDisc := reducedDiscriminant p
+      runningRb := runningRbinv := scalarMatrix(n,1)$Mat
+      -- runningRb    = basis matrix of current order
+      -- runningRbinv = inverse basis matrix of current order
+      -- these are wrt the original basis for F
+      runningRbden : R := 1
+      -- runningRbden = denominator for current basis matrix
+      empty? singList => [runningRb, runningRbden, runningRbinv]
+      for prime in singList repeat
+        lb := padicLocalIntegralBasis(p,disc,redDisc,prime)
+        rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
+        disc := lb.discr
+        mat := vertConcat(rbden * runningRb,runningRbden * rb)
+        runningRbden := runningRbden * rbden
+        runningRb := squareTop rowEchelon(mat,runningRbden)
+        --runningRb := squareTop rowEch mat
+        runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
+      [runningRb, runningRbden, runningRbinv]
+
+@
+<<PWFFINTB.dotabb>>=
+"PWFFINTB" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PWFFINTB"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"PWFFINTB" -> "MONOGEN"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PLEQN ParametricLinearEquations}
+\pagehead{ParametricLinearEquations}{PLEQN}
+\pagepic{ps/v104parametriclinearequations.ps}{PLEQN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+\begin{verbatim}
+++ This package completely solves a parametric linear system of equations
+++ by decomposing the set of all parametric values for which the linear
+++ system is consistent into a union of quasi-algebraic  sets (which need
+++ not be irredundant, but most of the time is). Each quasi-algebraic
+++ set is described by a list of polynomials that vanish on the set, and
+++ a list of polynomials that vanish at no point of the set.
+++ For each quasi-algebraic set, the solution of the linear system
+++ is given, as a particular solution and  a basis of the homogeneous
+++ system.
+++ The parametric linear system should be given in matrix form, with
+++ a coefficient matrix and a right hand side vector. The entries
+++ of the coefficient matrix and right hand side vector should be
+++ polynomials in the parametric variables, over a Euclidean domain
+++ of characteristic zero.
+++
+++ If the system is homogeneous, the right hand side need not be given.
+++ The right hand side can also be  replaced by an indeterminate vector,
+++ in which case, the conditions required for consistency will also be
+++ given.
+++
+++ The package has other facilities for saving results to external
+++ files, as well as solving the system for a specified minimum rank.
+++ Altogether there are 12 mode maps for psolve, as explained below.
+
+-- modified to conform with new runtime system 06/04/90
+-- updated with comments for MB, 02/16/94
+-- also cleaned up some unnecessary arguments in regime routine
+--
+-- MB: In order to allow the rhs to be indeterminate, while working
+-- mainly with the parametric variables on the lhs (less number of
+-- variables), certain conversions of internal representation from
+-- GR to Polynomial R and Fraction Polynomial R are done.  At the time
+-- of implementation, I thought that this may be more efficient.  I
+-- have not done any comparison since that requires rewriting the
+-- package.  My own application needs to call this package quite often,
+-- and most computations involves only polynomials in the parametric
+-- variables.
+
+-- The 12 modes of psolve are probably not all necessary.  Again, I
+-- was thinking that if there are many regimes and many ranks, then
+-- the output is quite big, and it may be nice to be able to save it
+-- and read the results in later to continue computing rather than
+-- recomputing.  Because of the combinatorial nature of the algorithm
+-- (computing all subdeterminants!), it does not take a very big matrix
+-- to get into many regimes.  But I now have second thoughts of this
+-- design, since most of the time, the results are just intermediate,
+-- passed to be further processed.  On the other hand, there is probably
+-- no penalty in leaving the options as is.
+\end{verbatim}
+<<package PLEQN ParametricLinearEquations>>=
+)abbrev package PLEQN ParametricLinearEquations
+++  Author: William Sit, spring 89
+ParametricLinearEquations(R,Var,Expon,GR):
+            Declaration == Definition where
+
+  R         :  Join(EuclideanDomain, CharacteristicZero)
+  -- Warning: does not work if R is a field! because of Fraction R
+  Var       :  Join(OrderedSet,ConvertibleTo (Symbol))
+  Expon     :  OrderedAbelianMonoidSup
+  GR        :  PolynomialCategory(R,Expon,Var)
+  F        == Fraction R
+  FILE ==> FileCategory
+  FNAME ==> FileName
+  GB  ==> EuclideanGroebnerBasisPackage
+--  GBINTERN ==> GroebnerInternalPackage
+  I   ==> Integer
+  L   ==> List
+  M   ==> Matrix
+  NNI ==> NonNegativeInteger
+  OUT ==> OutputForm
+  P   ==> Polynomial
+  PI  ==> PositiveInteger
+  SEG ==> Segment
+  SM  ==> SquareMatrix
+  S   ==> String
+  V   ==> Vector
+  mf    ==> MultivariateFactorize(Var,Expon,R,GR)
+  rp    ==> GB(R,Expon,Var,GR)
+  gb    ==> GB(R,Expon,Var,GR)
+  PR    ==> P R
+  GF    ==> Fraction PR
+  plift ==> PolynomialCategoryLifting(Expon,Var,R,GR,GF)
+  Inputmode ==> Integer
+  groebner ==> euclideanGroebner
+  redPol  ==> euclideanNormalForm
+
+-- MB: The following macros are data structures to store mostly
+-- intermediate results
+-- Rec stores a subdeterminant with corresponding row and column indices
+-- Fgb is a Groebner basis for the ideal generated by the subdeterminants
+--     of a given rank.
+-- Linsys specifies a linearly independent system of a given system
+--     assuming a given rank, using given row and column indices
+-- Linsoln stores the solution to the parametric linear system as a basis
+--     and a particular solution (for a given regime)
+-- Rec2 stores the rank, and a list of subdeterminants of that rank,
+--     and a Groebner basis for the ideal they generate.
+-- Rec3 stores a regime and the corresponding solution; the regime is
+--     given by a list of equations (eqzro) and one inequation (neqzro)
+--     describing the quasi-algebraic set which is the regime; the
+--     additional consistency conditions due to the rhs is given by wcond.
+-- Ranksolns stores a list of regimes and their solutions, and the number
+--     of regimes all together.
+-- Rec8 (temporary) stores a quasi-algebraic set with an indication
+-- whether it is empty (sysok = false) or not (sysok = true).
+
+-- I think psolve should be renamed parametricSolve, or even
+-- parametricLinearSolve.  On the other hand, may be just solve will do.
+-- Please feel free to change it to conform with system conventions.
+-- Most psolve routines return a list of regimes and solutions,
+-- except those that output to file when the number of regimes is
+-- returned instead.
+-- This version has been tested on the pc version 1.608 March 13, 1992
+
+  Rec   ==> Record(det:GR,rows:L I,cols:L I)
+  Eqns  ==> L Rec
+  Fgb   ==> L GR  -- groebner basis
+  Linsoln   ==> Record(partsol:V GF,basis:L V GF)
+  Linsys    ==> Record(mat:M GF,vec:L GF,rank:NNI,rows:L I,cols:L I)
+  Rec2  ==> Record(rank:NNI,eqns:Eqns,fgb:Fgb)
+  RankConds ==> L Rec2
+  Rec3  ==> Record(eqzro:L GR, neqzro:L GR,wcond:L PR, bsoln:Linsoln)
+  Ranksolns ==> Record(rgl:L Rec3,rgsz:I)
+  Rec8 ==> Record(sysok:Boolean, z0:L GR, n0:L GR)
+
+
+  Declaration == with
+      psolve: (M GR, L GR) -> L Rec3
+        ++ psolve(c,w) solves c z = w for all possible ranks
+        ++ of the matrix c and given right hand side vector w
+        -- this is mode 1
+      psolve: (M GR, L Symbol) -> L Rec3
+        ++ psolve(c,w) solves c z = w for all possible ranks
+        ++ of the matrix c and indeterminate right hand side w
+        -- this is mode 2
+      psolve:  M GR        -> L Rec3
+        ++ psolve(c) solves the homogeneous linear system
+        ++ c z = 0 for all possible ranks of the matrix c
+        -- this is mode 3
+      psolve: (M GR, L GR, PI) -> L Rec3
+        ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
+        ++ of the matrix c and given right hand side vector w
+        -- this is mode 4
+      psolve: (M GR, L Symbol, PI) -> L Rec3
+        ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
+        ++ of the matrix c and indeterminate right hand side w
+        -- this is mode 5
+      psolve: (M GR,       PI) -> L Rec3
+        ++ psolve(c) solves the homogeneous linear system
+        ++ c z = 0 for all possible ranks >= k of the matrix c
+        -- this is mode 6
+      psolve: (M GR, L GR, S) -> I
+        ++ psolve(c,w,s) solves c z = w for all possible ranks
+        ++ of the matrix c and given right hand side vector w,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 7
+      psolve: (M GR, L Symbol, S) -> I
+        ++ psolve(c,w,s) solves c z = w for all possible ranks
+        ++ of the matrix c and indeterminate right hand side w,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 8
+      psolve: (M GR,       S) -> I
+        ++ psolve(c,s) solves c z = 0 for all possible ranks
+        ++ of the matrix c and given right hand side vector w,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 9
+      psolve: (M GR, L GR, PI, S) -> I
+        ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
+        ++ of the matrix c and given right hand side w,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 10
+      psolve: (M GR, L Symbol, PI, S) -> I
+        ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
+        ++ of the matrix c and indeterminate right hand side w,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 11
+      psolve: (M GR,       PI, S) -> I
+        ++ psolve(c,k,s) solves c z = 0 for all possible ranks >= k
+        ++ of the matrix c,
+        ++ writes the results to a file named s, and returns the
+        ++ number of regimes
+        -- this is mode 12
+
+      wrregime   : (L Rec3, S) -> I
+        ++ wrregime(l,s) writes a list of regimes to a file named s
+        ++ and returns the number of regimes written
+      rdregime   : S -> L Rec3
+        ++ rdregime(s) reads in a list from a file with name s
+
+        -- for internal use only --
+      -- these are exported so my other packages can use them
+
+      bsolve: (M GR, L GF, NNI, S, Inputmode) -> Ranksolns
+        ++ bsolve(c, w, r, s, m) returns a list of regimes and
+        ++ solutions of the system c z = w for ranks at least r;
+        ++ depending on the mode m chosen, it writes the output to
+        ++ a file given by the string s.
+      dmp2rfi: GR -> GF
+        ++ dmp2rfi(p) converts p to target domain
+      dmp2rfi: M GR -> M GF
+        ++ dmp2rfi(m) converts m to target domain
+      dmp2rfi: L GR -> L GF
+        ++ dmp2rfi(l) converts l to target domain
+      se2rfi:  L Symbol -> L GF
+        ++ se2rfi(l) converts l to target domain
+      pr2dmp: PR -> GR
+        ++ pr2dmp(p) converts p to target domain
+      hasoln: (Fgb, L GR) -> Rec8
+        ++ hasoln(g, l) tests whether the quasi-algebraic set
+        ++ defined by p = 0 for p in g and q ^= 0 for q in l
+        ++ is empty or not and returns a simplified definition
+        ++ of the quasi-algebraic set
+        -- this is now done in QALGSET package
+      ParCondList: (M GR,NNI) -> RankConds
+        ++ ParCondList(c,r) computes a list of subdeterminants of each
+        ++ rank >= r of the matrix c and returns
+        ++ a groebner basis for the
+        ++ ideal they generate
+      redpps: (Linsoln, Fgb) -> Linsoln
+        ++ redpps(s,g) returns the simplified form of s after reducing
+        ++ modulo a groebner basis g
+
+
+
+--               L O C A L    F U N C T I O N S
+
+      B1solve: Linsys -> Linsoln
+        ++ B1solve(s) solves the system (s.mat) z = s.vec
+        ++ for the variables given by the column indices of s.cols
+        ++ in terms of the other variables and the right hand side s.vec
+        ++ by assuming that the rank is s.rank,
+        ++ that the system is consistent, with the linearly
+        ++ independent equations indexed by the given row indices s.rows;
+        ++ the coefficients in s.mat involving parameters are treated as
+        ++ polynomials.  B1solve(s) returns a particular solution to the
+        ++ system and a basis of the homogeneous system (s.mat) z = 0.
+      factorset: GR -> L GR
+        ++ factorset(p) returns the set of irreducible factors of p.
+      maxrank: RankConds -> NNI
+        ++ maxrank(r) returns the maximum rank in the list r of regimes
+      minrank: RankConds -> NNI
+        ++ minrank(r) returns the minimum rank in the list r of regimes
+      minset: L L GR -> L L GR
+        ++ minset(sl) returns the sublist of sl consisting of the minimal
+        ++ lists (with respect to inclusion) in the list sl of lists
+      nextSublist: (I, I) -> L L I
+        ++ nextSublist(n,k) returns a list of k-subsets of {1, ..., n}.
+      overset?: (L GR, L L GR) -> Boolean
+        ++ overset?(s,sl) returns true if s properly a sublist of a member
+        ++ of sl; otherwise it returns false
+      ParCond    : (M GR,NNI) -> Eqns
+        ++ ParCond(m,k) returns the list of all k by k subdeterminants in
+        ++ the matrix m
+      redmat: (M GR, Fgb) -> M GR
+        ++ redmat(m,g) returns a matrix whose entries are those of m
+        ++ modulo the ideal generated by the groebner basis g
+      regime: (Rec,M GR,L GF,L L GR,NNI,NNI,Inputmode) -> Rec3
+        ++ regime(y,c, w, p, r, rm, m) returns a regime,
+        ++ a list of polynomials specifying the consistency conditions,
+        ++ a particular solution and basis representing the general
+        ++ solution of the parametric linear system c z = w
+        ++ on that regime. The regime returned depends on
+        ++ the subdeterminant y.det and the row and column indices.
+        ++ The solutions are simplified using the assumption that
+        ++ the system has rank r and maximum rank rm. The list p
+        ++ represents a list of list of factors of polynomials in
+        ++ a groebner basis of the ideal generated by higher order
+        ++ subdeterminants, and ius used for the simplification.
+        ++ The mode m
+        ++ distinguishes the cases when the system is homogeneous,
+        ++ or the right hand side is arbitrary, or when there is no
+        ++ new right hand side variables.
+      sqfree: GR -> GR
+        ++ sqfree(p) returns the product of square free factors of p
+      inconsistent?: L GR -> Boolean
+        ++ inconsistant?(pl) returns true if the system of equations
+        ++ p = 0 for p in pl is inconsistent.  It is assumed
+        ++ that pl is a groebner basis.
+        -- this is needed because of change to
+        -- EuclideanGroebnerBasisPackage
+      inconsistent?: L PR -> Boolean
+        ++ inconsistant?(pl) returns true if the system of equations
+        ++ p = 0 for p in pl is inconsistent.  It is assumed
+        ++ that pl is a groebner basis.
+        -- this is needed because of change to
+        -- EuclideanGroebnerBasisPackage
+
+  Definition == add
+
+    inconsistent?(pl:L GR):Boolean ==
+      for p in pl repeat
+        ground? p => return true
+      false
+    inconsistent?(pl:L PR):Boolean ==
+      for p in pl repeat
+        ground? p => return true
+      false
+
+    B1solve (sys:Linsys):Linsoln ==
+      i,j,i1,j1:I
+      rss:L I:=sys.rows
+      nss:L I:=sys.cols
+      k:=sys.rank
+      cmat:M GF:=sys.mat
+      n:=ncols cmat
+      frcols:L I:=setDifference$(L I) (expand$(SEG I) (1..n), nss)
+      w:L GF:=sys.vec
+      p:V GF:=new(n,0)
+      pbas:L V GF:=[]
+      if k ^= 0 then
+        augmat:M GF:=zero(k,n+1)
+        for i in rss for i1 in 1.. repeat
+          for j in nss for j1 in 1.. repeat
+            augmat(i1,j1):=cmat(i,j)
+          for j in frcols for j1 in k+1.. repeat
+            augmat(i1,j1):=-cmat(i,j)
+          augmat(i1,n+1):=w.i
+        augmat:=rowEchelon$(M GF) augmat
+        for i in nss for i1 in 1.. repeat p.i:=augmat(i1,n+1)
+        for j in frcols for j1 in k+1.. repeat
+          pb:V GF:=new(n,0)
+          pb.j:=1
+          for i in nss for i1 in 1.. repeat
+            pb.i:=augmat(i1,j1)
+          pbas:=cons(pb,pbas)
+      else
+        for j in frcols for j1 in k+1.. repeat
+          pb:V GF:=new(n,0)
+          pb.j:=1
+          pbas:=cons(pb,pbas)
+      [p,pbas]
+
+    regime (y, coef, w, psbf, rk, rkmax, mode) ==
+      i,j:I
+      -- use the y.det nonzero to simplify the groebner basis
+      -- of ideal generated by higher order subdeterminants
+      ydetf:L GR:=factorset y.det
+      yzero:L GR:=
+        rk = rkmax => nil$(L GR)
+        psbf:=[setDifference(x, ydetf) for x in psbf]
+        groebner$gb [*/x for x in psbf]
+      -- simplify coefficients by modulo ideal
+      nc:M GF:=dmp2rfi redmat(coef,yzero)
+      -- solve the system
+      rss:L I:=y.rows;  nss:L I :=y.cols
+      sys:Linsys:=[nc,w,rk,rss,nss]$Linsys
+      pps:= B1solve(sys)
+      pp:=pps.partsol
+      frows:L I:=setDifference$(L I) (expand$(SEG I) (1..nrows coef),rss)
+      wcd:L PR:= []
+      -- case homogeneous rhs
+      entry? (mode, [3,6,9,12]$(L I)) =>
+               [yzero, ydetf,wcd, redpps(pps, yzero)]$Rec3
+      -- case arbitrary rhs, pps not reduced
+      for i in frows repeat
+          weqn:GF:=+/[nc(i,j)*(pp.j) for j in nss]
+          wnum:PR:=numer$GF (w.i - weqn)
+          wnum = 0 => "trivially satisfied"
+          ground? wnum => return [yzero, ydetf,[1$PR]$(L PR),pps]$Rec3
+          wcd:=cons(wnum,wcd)
+      entry? (mode, [2,5,8,11]$(L I)) => [yzero, ydetf, wcd, pps]$Rec3
+      -- case no new rhs variable
+      if not empty? wcd then _
+        yzero:=removeDuplicates append(yzero,[pr2dmp pw for pw in wcd])
+      test:Rec8:=hasoln (yzero, ydetf)
+      not test.sysok => [test.z0, test.n0, [1$PR]$(L PR), pps]$Rec3
+      [test.z0, test.n0, [], redpps(pps, test.z0)]$Rec3
+
+    bsolve (coeff, w, h, outname, mode) ==
+      r:=nrows coeff
+--    n:=ncols coeff
+      r ^= #w => error "number of rows unequal on lhs and rhs"
+      newfile:FNAME
+      rksoln:File Rec3
+      count:I:=0
+      lrec3:L Rec3:=[]
+      filemode:Boolean:= entry? (mode, [7,8,9,10,11,12]$(L I))
+      if filemode then
+        newfile:=new$FNAME  ("",outname,"regime")
+        rksoln:=open$(File Rec3) newfile
+      y:Rec
+      k:NNI
+      rrcl:RankConds:=
+        entry? (mode,[1,2,3,7,8,9]$(L I)) => ParCondList (coeff,0)
+        entry? (mode,[4,5,6,10,11,12]$(L I)) => ParCondList (coeff,h)
+      rkmax:=maxrank rrcl
+      rkmin:=minrank rrcl
+      for k in rkmax-rkmin+1..1 by -1 repeat
+        rk:=rrcl.k.rank
+        pc:Eqns:=rrcl.k.eqns
+        psb:Fgb:= (if rk=rkmax then [] else rrcl.(k+1).fgb)
+        psbf:L L GR:= [factorset x for x in psb]
+        psbf:= minset(psbf)
+        for y in pc repeat
+          rec3:Rec3:= regime (y, coeff, w, psbf, rk, rkmax, mode)
+          inconsistent? rec3.wcond => "incompatible system"
+          if filemode then write_!(rksoln, rec3)
+          else lrec3:= cons(rec3, lrec3)
+          count:=count+1
+      if filemode then close_! rksoln
+      [lrec3, count]$Ranksolns
+
+    factorset y ==
+      ground? y => []
+      [j.factor for j in factors(factor$mf y)]
+
+    ParCondList (mat, h) ==
+      rcl: RankConds:= []
+      ps: L GR:=[]
+      pc:Eqns:=[]
+      npc: Eqns:=[]
+      psbf: Fgb:=[]
+      rc: Rec
+      done: Boolean := false
+      r:=nrows mat
+      n:=ncols mat
+      maxrk:I:=min(r,n)
+      k:NNI
+      for k in min(r,n)..h by -1 until done repeat
+        pc:= ParCond(mat,k)
+        npc:=[]
+        (empty? pc) and (k >= 1) => maxrk:= k - 1
+        if ground? pc.1.det -- only one is sufficient (neqzro = {})
+        then (npc:=pc; done:=true; ps := [1$GR])
+        else
+          zro:L GR:= (if k = maxrk then [] else rcl.1.fgb)
+          covered:Boolean:=false
+          for rc in pc until covered repeat
+            p:GR:= redPol$rp (rc.det, zro)
+            p = 0 => "incompatible or covered subdeterminant"
+            test:=hasoln(zro, [rc.det])
+--          zroideal:=ideal(zro)
+--          inRadical? (p, zroideal) => "incompatible or covered"
+            ^test.sysok => "incompatible or covered"
+-- The next line is WRONG! cannot replace zro by test.z0
+--          zro:=groebner$gb (cons(*/test.n0, test.z0))
+            zro:=groebner$gb (cons(p,zro))
+            npc:=cons(rc,npc)
+            done:= covered:= inconsistent? zro
+          ps:=zro
+        pcl: Rec2:= construct(k,npc,ps)
+        rcl:=cons(pcl,rcl)
+      rcl
+
+    redpps(pps, zz) ==
+      pv:=pps.partsol
+      r:=#pv
+      pb:=pps.basis
+      n:=#pb + 1
+      nummat:M GR:=zero(r,n)
+      denmat:M GR:=zero(r,n)
+      for i in  1..r repeat
+        nummat(i,1):=pr2dmp numer$GF pv.i
+        denmat(i,1):=pr2dmp denom$GF pv.i
+      for j in 2..n repeat
+        for i in 1..r  repeat
+          nummat(i,j):=pr2dmp numer$GF (pb.(j-1)).i
+          denmat(i,j):=pr2dmp denom$GF (pb.(j-1)).i
+      nummat:=redmat(nummat, zz)
+      denmat:=redmat(denmat, zz)
+      for i in 1..r repeat
+        pv.i:=(dmp2rfi nummat(i,1))/(dmp2rfi denmat(i,1))
+      for j in 2..n repeat
+        pbj:V GF:=new(r,0)
+        for i in 1..r repeat
+          pbj.i:=(dmp2rfi nummat(i,j))/(dmp2rfi  denmat(i,j))
+        pb.(j-1):=pbj
+      [pv, pb]
+
+    dmp2rfi (mat:M GR): M GF ==
+      r:=nrows mat
+      n:=ncols mat
+      nmat:M GF:=zero(r,n)
+      for i in 1..r repeat
+        for j in 1..n repeat
+          nmat(i,j):=dmp2rfi mat(i,j)
+      nmat
+
+    dmp2rfi (vl: L GR):L GF ==
+      [dmp2rfi v for v in vl]
+
+    psolve (mat:M GR, w:L GR): L Rec3 ==
+      bsolve(mat, dmp2rfi w, 1, "nofile", 1).rgl
+    psolve (mat:M GR, w:L Symbol): L Rec3 ==
+      bsolve(mat,  se2rfi w, 1, "nofile", 2).rgl
+    psolve (mat:M GR): L Rec3 ==
+      bsolve(mat, [0$GF for i in 1..nrows mat], 1, "nofile", 3).rgl
+
+    psolve (mat:M GR, w:L GR, h:PI): L Rec3 ==
+      bsolve(mat, dmp2rfi w, h::NNI, "nofile", 4).rgl
+    psolve (mat:M GR, w:L Symbol, h:PI): L Rec3 ==
+      bsolve(mat, se2rfi w, h::NNI, "nofile", 5).rgl
+    psolve (mat:M GR, h:PI): L Rec3 ==
+      bsolve(mat, [0$GF for i in 1..nrows mat], h::NNI, "nofile", 6).rgl
+
+    psolve (mat:M GR, w:L GR, outname:S): I ==
+      bsolve(mat, dmp2rfi w, 1, outname, 7).rgsz
+    psolve (mat:M GR, w:L Symbol, outname:S): I ==
+      bsolve(mat, se2rfi w, 1, outname, 8).rgsz
+    psolve (mat:M GR, outname:S): I ==
+      bsolve(mat, [0$GF for i in 1..nrows mat], 1, outname, 9).rgsz
+
+    nextSublist (n,k) ==
+      n <= 0 => []
+      k <= 0 => [ nil$(List Integer) ]
+      k > n => []
+      n = 1 and k = 1 => [[1]]
+      mslist: L L I:=[]
+      for ms in nextSublist(n-1,k-1) repeat
+        mslist:=cons(append(ms,[n]),mslist)
+      append(nextSublist(n-1,k), mslist)
+
+    psolve (mat:M GR, w:L GR, h:PI, outname:S): I ==
+      bsolve(mat, dmp2rfi w, h::NNI, outname, 10).rgsz
+    psolve (mat:M GR, w:L Symbol, h:PI, outname:S): I ==
+      bsolve(mat, se2rfi w, h::NNI, outname, 11).rgsz
+    psolve (mat:M GR, h:PI, outname:S): I ==
+      bsolve(mat,[0$GF for i in 1..nrows mat],h::NNI,outname, 12).rgsz
+
+    hasoln (zro,nzro) ==
+      empty? zro => [true, zro, nzro]
+      zro:=groebner$gb zro
+      inconsistent? zro => [false, zro, nzro]
+      empty? nzro =>[true, zro, nzro]
+      pnzro:GR:=redPol$rp (*/nzro, zro)
+      pnzro = 0 => [false, zro, nzro]
+      nzro:=factorset pnzro
+      psbf:L L GR:= minset [factorset p for p in zro]
+      psbf:= [setDifference(x, nzro) for x in psbf]
+      entry? ([], psbf) => [false, zro, nzro]
+      zro:=groebner$gb [*/x for x in psbf]
+      inconsistent? zro => [false, zro, nzro]
+      nzro:=[redPol$rp (p,zro) for p in nzro]
+      nzro:=[p for p in nzro | ^(ground? p)]
+      [true, zro, nzro]
+
+
+
+    se2rfi w == [coerce$GF monomial$PR (1$PR, wi, 1) for wi in w]
+
+    pr2dmp p ==
+      ground? p => (ground p)::GR
+      algCoerceInteractive(p,PR,GR)$(Lisp) pretend GR
+
+    wrregime (lrec3, outname) ==
+      newfile:FNAME:=new$FNAME ("",outname,"regime")
+      rksoln: File Rec3:=open$(File Rec3) newfile
+      count:I:=0  -- number of distinct regimes
+--      rec3: Rec3
+      for rec3 in lrec3 repeat
+          write_!(rksoln, rec3)
+          count:=count+1
+      close_!(rksoln)
+      count
+
+    dmp2rfi (p:GR):GF ==
+      map$plift ((convert #1)@Symbol::GF, #1::PR::GF, p)
+
+
+    rdregime inname ==
+      infilename:=filename$FNAME ("",inname, "regime")
+      infile: File Rec3:=open$(File Rec3) (infilename, "input")
+      rksoln:L Rec3:=[]
+      rec3:Union(Rec3, "failed"):=readIfCan_!$(File Rec3) (infile)
+      while rec3 case Rec3 repeat
+        rksoln:=cons(rec3::Rec3,rksoln) -- replace : to :: for AIX
+        rec3:=readIfCan_!$(File Rec3) (infile)
+      close_!(infile)
+      rksoln
+
+    maxrank rcl ==
+      empty? rcl => 0
+      "max"/[j.rank for j in rcl]
+
+    minrank rcl ==
+      empty? rcl => 0
+      "min"/[j.rank for j in rcl]
+
+    minset lset ==
+      empty? lset => lset
+      [x for x in lset | ^(overset?(x,lset))]
+
+    sqfree p == */[j.factor for j in factors(squareFree p)]
+
+
+    ParCond (mat, k) ==
+      k = 0 => [[1, [], []]$Rec]
+      j:NNI:=k::NNI
+      DetEqn :Eqns := []
+      r:I:= nrows(mat)
+      n:I:= ncols(mat)
+      k > min(r,n) => error "k exceeds maximum possible rank "
+      found:Boolean:=false
+      for rss in nextSublist(r, k) until found repeat
+        for nss in nextSublist(n, k) until found repeat
+          matsub := mat(rss, nss) pretend SM(j, GR)
+          detmat := determinant(matsub)
+          if detmat ^= 0 then
+            found:= (ground? detmat)
+            detmat:=sqfree detmat
+            neweqn:Rec:=construct(detmat,rss,nss)
+            DetEqn:=cons(neweqn, DetEqn)
+      found => [first DetEqn]$Eqns
+      sort(degree #1.det < degree #2.det, DetEqn)
+
+
+
+    overset?(p,qlist) ==
+      empty? qlist => false
+      or/[(brace$(Set GR) q) <$(Set GR) (brace$(Set GR) p) _
+                                                for q in qlist]
+
+
+    redmat (mat,psb) ==
+      i,j:I
+      r:=nrows(mat)
+      n:=ncols(mat)
+      newmat: M GR:=zero(r,n)
+      for i in 1..r repeat
+        for j in 1..n repeat
+          p:GR:=mat(i,j)
+          ground? p => newmat(i,j):=p
+          newmat(i,j):=redPol$rp (p,psb)
+      newmat
+
+@
+<<PLEQN.dotabb>>=
+"PLEQN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PLEQN"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PLEQN" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PARPC2 ParametricPlaneCurveFunctions2}
+\pagehead{ParametricPlaneCurveFunctions2}{PARPC2}
+\pagepic{ps/v104parametricplanecurvefunctions2.ps}{PARPC2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PARPC2 ParametricPlaneCurveFunctions2>>=
+)abbrev package PARPC2 ParametricPlaneCurveFunctions2
+++ Description:
+++ This package \undocumented
+ParametricPlaneCurveFunctions2(CF1: Type, CF2:Type): with
+  map: (CF1 -> CF2, ParametricPlaneCurve(CF1)) -> ParametricPlaneCurve(CF2)
+	++ map(f,x) \undocumented
+ == add
+  map(f, c) == curve(f coordinate(c,1), f coordinate(c, 2))
+
+@
+<<PARPC2.dotabb>>=
+"PARPC2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PARPC2"]
+"TYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=TYPE"]
+"PARPC2" -> "TYPE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PARSC2 ParametricSpaceCurveFunctions2}
+\pagehead{ParametricSpaceCurveFunctions2}{PARSC2}
+\pagepic{ps/v104parametricspacecurvefunctions2.ps}{PARSC2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PARSC2 ParametricSpaceCurveFunctions2>>=
+)abbrev package PARSC2 ParametricSpaceCurveFunctions2
+++ Description:
+++ This package \undocumented
+ParametricSpaceCurveFunctions2(CF1: Type, CF2:Type): with
+  map: (CF1 -> CF2, ParametricSpaceCurve(CF1)) -> ParametricSpaceCurve(CF2)
+	++ map(f,x) \undocumented
+ == add
+  map(f, c) == curve(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
+
+@
+<<PARSC2.dotabb>>=
+"PARSC2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PARSC2"]
+"TYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=TYPE"]
+"PARSC2" -> "TYPE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PARSU2 ParametricSurfaceFunctions2}
+\pagehead{ParametricSurfaceFunctions2}{PARSU2}
+\pagepic{ps/v104parametricsurfacefunctions2.ps}{PARSU2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PARSU2 ParametricSurfaceFunctions2>>=
+)abbrev package PARSU2 ParametricSurfaceFunctions2
+++ Description:
+++ This package \undocumented
+ParametricSurfaceFunctions2(CF1: Type, CF2:Type): with
+  map: (CF1 -> CF2, ParametricSurface(CF1)) -> ParametricSurface(CF2)
+	++ map(f,x) \undocumented
+ == add
+  map(f, c) == surface(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
+
+@
+<<PARSU2.dotabb>>=
+"PARSU2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PARSU2"]
+"TYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=TYPE"]
+"PARSU2" -> "TYPE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFRPAC PartialFractionPackage}
+\pagehead{PartialFractionPackage}{PFRPAC}
+\pagepic{ps/v104partialfractionpackage.ps}{PFRPAC}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFRPAC PartialFractionPackage>>=
+)abbrev package PFRPAC PartialFractionPackage
+++ Author: Barry M. Trager
+++ Date Created: 1992
+++ BasicOperations:
+++ Related Constructors: PartialFraction
+++ Also See:
+++ AMS Classifications:
+++ Keywords: partial fraction, factorization, euclidean domain
+++ References:
+++ Description:
+++   The package \spadtype{PartialFractionPackage} gives an easier
+++   to use interfact the domain \spadtype{PartialFraction}.
+++   The user gives a fraction of polynomials, and a variable and
+++   the package converts it to the proper datatype for the
+++   \spadtype{PartialFraction} domain.
+
+PartialFractionPackage(R): Cat == Capsule where
+--  R : UniqueFactorizationDomain -- not yet supported
+   R : Join(EuclideanDomain, CharacteristicZero)
+   FPR ==> Fraction Polynomial R
+   INDE ==> IndexedExponents Symbol
+   PR ==> Polynomial R
+   SUP ==> SparseUnivariatePolynomial
+   Cat == with
+      partialFraction: (FPR, Symbol) -> Any
+         ++ partialFraction(rf, var) returns the partial fraction decomposition
+         ++ of the rational function rf with respect to the variable var.
+      partialFraction: (PR, Factored PR, Symbol) -> Any
+         ++ partialFraction(num, facdenom, var) returns the partial fraction
+         ++ decomposition of the rational function whose numerator is num and
+         ++ whose factored denominator is facdenom with respect to the variable var.
+   Capsule == add
+      partialFraction(rf, v) ==
+         df := factor(denom rf)$MultivariateFactorize(Symbol, INDE,R,PR)
+         partialFraction(numer rf, df, v)
+
+      makeSup(p:Polynomial R, v:Symbol) : SparseUnivariatePolynomial FPR ==
+         up := univariate(p,v)
+         map(#1::FPR,up)$UnivariatePolynomialCategoryFunctions2(PR, SUP PR, FPR, SUP FPR)
+
+      partialFraction(p, facq, v) ==
+         up := UnivariatePolynomial(v, Fraction Polynomial R)
+         fup := Factored up
+         ffact : List(Record(irr:up,pow:Integer))
+         ffact:=[[makeSup(u.factor,v) pretend up,u.exponent]
+                      for u in factors facq]
+         fcont:=makeSup(unit facq,v) pretend up
+         nflist:fup := fcont*(*/[primeFactor(ff.irr,ff.pow) for ff in ffact])
+         pfup:=partialFraction(makeSup(p,v) pretend up, nflist)$PartialFraction(up)
+         coerce(pfup)$AnyFunctions1(PartialFraction up)
+
+@
+<<PFRPAC.dotabb>>=
+"PFRPAC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFRPAC"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PFRPAC" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PARTPERM PartitionsAndPermutations}
+\pagehead{PartitionsAndPermutations}{PARTPERM}
+\pagepic{ps/v104partitionsandpermutations.ps}{PARTPERM}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PARTPERM PartitionsAndPermutations>>=
+)abbrev package PARTPERM PartitionsAndPermutations
+++ Author: William H. Burge
+++ Date Created: 29 October 1987
+++ Date Last Updated: 3 April 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: partition, permutation
+++ References:
+++ Description: PartitionsAndPermutations contains
+++ functions for generating streams of integer partitions,
+++ and streams of sequences of integers
+++ composed from a multi-set.
+PartitionsAndPermutations: Exports == Implementation where
+  I   ==> Integer
+  L   ==> List
+  ST  ==> Stream
+  ST1 ==> StreamFunctions1
+  ST2 ==> StreamFunctions2
+  ST3 ==> StreamFunctions3
+ 
+  Exports ==> with
+ 
+    partitions: (I,I,I) -> ST L I
+      ++\spad{partitions(p,l,n)} is the stream of partitions
+      ++ of n whose number of parts is no greater than p
+      ++ and whose largest part is no greater than l.
+    partitions: I -> ST L I
+      ++\spad{partitions(n)} is the stream of all partitions of n.
+    partitions: (I,I) -> ST L I
+      ++\spad{partitions(p,l)} is the stream of all
+      ++ partitions whose number of
+      ++ parts and largest part are no greater than p and l.
+    conjugate: L I -> L I
+      ++\spad{conjugate(pt)} is the conjugate of the partition pt.
+    conjugates: ST L I -> ST L I
+      ++\spad{conjugates(lp)} is the stream of conjugates of a stream
+      ++ of partitions lp.
+    shuffle: (L I,L I) -> ST L I
+      ++\spad{shuffle(l1,l2)} forms the stream of all shuffles of l1
+      ++ and l2, i.e. all sequences that can be formed from
+      ++ merging l1 and l2.
+    shufflein: (L I,ST L I) -> ST L I
+      ++\spad{shufflein(l,st)} maps shuffle(l,u) on to all
+      ++ members u of st, concatenating the results.
+    sequences: (L I,L I) -> ST L I
+      ++\spad{sequences(l1,l2)} is the stream of all sequences that
+      ++ can be composed from the multiset defined from
+      ++ two lists of integers l1 and l2.
+      ++ For example,the pair \spad{([1,2,4],[2,3,5])} represents
+      ++ multi-set with 1 \spad{2}, 2 \spad{3}'s, and 4 \spad{5}'s.
+    sequences: L I -> ST L I
+      ++ \spad{sequences([l0,l1,l2,..,ln])} is the set of
+      ++  all sequences formed from
+      ++ \spad{l0} 0's,\spad{l1} 1's,\spad{l2} 2's,...,\spad{ln} n's.
+    permutations: I -> ST L I
+      ++\spad{permutations(n)} is the stream of permutations
+      ++ formed from \spad{1,2,3,...,n}.
+ 
+  Implementation ==> add
+ 
+    partitions(M,N,n) ==
+      zero? n => concat(empty()$L(I),empty()$(ST L I))
+      zero? M or zero? N or n < 0 => empty()
+      c := map(concat(N,#1),partitions(M - 1,N,n - N))
+      concat(c,partitions(M,N - 1,n))
+ 
+    partitions n == partitions(n,n,n)
+ 
+    partitions(M,N)==
+      aaa : L ST L I := [partitions(M,N,i) for i in 0..M*N]
+      concat(aaa :: ST ST L I)$ST1(L I)
+ 
+    -- nogreq(n,l) is the number of elements of l that are greater or
+    -- equal to n
+    nogreq: (I,L I) -> I
+    nogreq(n,x) == +/[1 for i in x | i >= n]
+ 
+    conjugate x ==
+      empty? x => empty()
+      [nogreq(i,x) for i in 1..first x]
+ 
+    conjugates z == map(conjugate,z)
+ 
+    shuffle(x,y)==
+      empty? x => concat(y,empty())$(ST L I)
+      empty? y => concat(x,empty())$(ST L I)
+      concat(map(concat(first x,#1),shuffle(rest x,y)),_
+             map(concat(first y,#1),shuffle(x,rest y)))
+ 
+    shufflein(x,yy) ==
+      concat(map(shuffle(x,#1),yy)$ST2(L I,ST L I))$ST1(L I)
+ 
+    -- rpt(n,m) is the list of n m's
+    rpt: (I,I) -> L I
+    rpt(n,m) == [m for i in 1..n]
+ 
+    -- zrpt(x,y) where x is [x0,x1,x2...] and y is [y0,y1,y2...]
+    -- is the stream [rpt(x0,y0),rpt(x1,y1),...]
+    zrpt: (L I,L I) -> ST L I
+    zrpt(x,y) == map(rpt,x :: ST I,y :: ST I)$ST3(I,I,L I)
+ 
+    sequences(x,y) ==
+      reduce(concat(empty()$L(I),empty()$(ST L I)),_
+                    shufflein,zrpt(x,y))$ST2(L I,ST L I)
+ 
+    sequences x == sequences(x,[i for i in 0..#x-1])
+ 
+    permutations n == sequences(rpt(n,1),[i for i in 1..n])
+
+@
+<<PARTPERM.dotabb>>=
+"PARTPERM" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PARTPERM"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PARTPERM" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PATTERN1 PatternFunctions1}
+\pagehead{PatternFunctions1}{PATTERN1}
+\pagepic{ps/v104patternfunctions1.ps}{PATTERN1}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PATTERN1 PatternFunctions1>>=
+)abbrev package PATTERN1 PatternFunctions1
+++ Utilities for handling patterns
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 5 Jul 1990
+++ Description: Tools for patterns;
+++ Keywords: pattern, matching.
+PatternFunctions1(R:SetCategory, D:Type): with
+    suchThat   : (Pattern R, D -> Boolean)       -> Pattern R
+      ++ suchThat(p, f) makes a copy of p and adds the predicate
+      ++ f to the copy, which is returned.
+    suchThat   : (Pattern R, List(D -> Boolean)) -> Pattern R
+      ++ \spad{suchThat(p, [f1,...,fn])} makes a copy of p and adds the
+      ++ predicate f1 and ... and fn to the copy, which is returned.
+    suchThat : (Pattern R, List Symbol, List D -> Boolean)  -> Pattern R
+      ++ \spad{suchThat(p, [a1,...,an], f)} returns a copy of p with
+      ++ the top-level predicate set to \spad{f(a1,...,an)}.
+    predicate  : Pattern R -> (D -> Boolean)
+      ++ predicate(p) returns the predicate attached to p, the
+      ++ constant function true if p has no predicates attached to it.
+    satisfy?   : (D, Pattern R) -> Boolean
+      ++ satisfy?(v, p) returns f(v) where f is the predicate
+      ++ attached to p.
+    satisfy?   : (List D, Pattern R) -> Boolean
+      ++ \spad{satisfy?([v1,...,vn], p)} returns \spad{f(v1,...,vn)} 
+      ++ where f is the
+      ++ top-level predicate attached to p.
+    addBadValue: (Pattern R, D) -> Pattern R
+      ++ addBadValue(p, v) adds v to the list of "bad values" for p;
+      ++ p is not allowed to match any of its "bad values".
+    badValues  : Pattern R -> List D
+      ++ badValues(p) returns the list of "bad values" for p;
+      ++ p is not allowed to match any of its "bad values".
+  == add
+    A1D ==> AnyFunctions1(D)
+    A1  ==> AnyFunctions1(D -> Boolean)
+    A1L ==> AnyFunctions1(List D -> Boolean)
+ 
+    applyAll: (List Any, D) -> Boolean
+    st      : (Pattern R, List Any) -> Pattern R
+ 
+    st(p, l)          == withPredicates(p, concat(predicates p, l))
+    predicate p       == applyAll(predicates p, #1)
+    addBadValue(p, v) == addBadValue(p, coerce(v)$A1D)
+    badValues p       == [retract(v)$A1D for v in getBadValues p]
+    suchThat(p, l, f) == setTopPredicate(copy p, l, coerce(f)$A1L)
+    suchThat(p:Pattern R, f:D -> Boolean) == st(p, [coerce(f)$A1])
+    satisfy?(d:D, p:Pattern R)            == applyAll(predicates p, d)
+ 
+    satisfy?(l:List D, p:Pattern R) ==
+      empty?((rec := topPredicate p).var) => true
+      retract(rec.pred)$A1L l
+ 
+    applyAll(l, d) ==
+      for f in l repeat
+        not(retract(f)$A1 d) => return false
+      true
+ 
+    suchThat(p:Pattern R, l:List(D -> Boolean)) ==
+      st(p, [coerce(f)$A1 for f in l])
+
+@
+<<PATTERN1.dotabb>>=
+"PATTERN1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PATTERN1"]
+"BASTYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=BASTYPE"]
+"KOERCE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=KOERCE"]
+"TYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=TYPE"]
+"PATTERN1" -> "BASTYPE"
+"PATTERN1" -> "KOERCE"
+"PATTERN1" -> "TYPE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PATTERN2 PatternFunctions2}
+\pagehead{PatternFunctions2}{PATTERN2}
+\pagepic{ps/v104patternfunctions2.ps}{PATTERN2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PATTERN2 PatternFunctions2>>=
+)abbrev package PATTERN2 PatternFunctions2
+++ Lifting of maps to patterns
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 12 Jan 1990
+++ Description: Lifts maps to patterns;
+++ Keywords: pattern, matching.
+PatternFunctions2(R:SetCategory, S:SetCategory): with
+    map: (R -> S, Pattern R) -> Pattern S
+      ++ map(f, p) applies f to all the leaves of p and
+      ++ returns the result as a pattern over S.
+  == add
+    map(f, p) ==
+      (r := (retractIfCan p)@Union(R, "failed")) case R =>
+        f(r::R)::Pattern(S)
+      (u := isOp p) case Record(op:BasicOperator, arg:List Pattern R) =>
+        ur := u::Record(op:BasicOperator, arg:List Pattern R)
+        (ur.op) [map(f, x) for x in ur.arg]
+      (v := isQuotient p) case Record(num:Pattern R, den:Pattern R) =>
+        vr := v::Record(num:Pattern R, den:Pattern R)
+        map(f, vr.num) / map(f, vr.den)
+      (l := isPlus p) case List(Pattern R) =>
+        reduce("+", [map(f, x) for x in l::List(Pattern R)])
+      (l := isTimes p) case List(Pattern R) =>
+        reduce("*", [map(f, x) for x in l::List(Pattern R)])
+      (x := isPower p) case
+       Record(val:Pattern R, exponent: Pattern R) =>
+        xr := x::Record(val:Pattern R, exponent: Pattern R)
+        map(f, xr.val) ** map(f, xr.exponent)
+      (w := isExpt p) case
+       Record(val:Pattern R, exponent: NonNegativeInteger) =>
+        wr := w::Record(val:Pattern R, exponent: NonNegativeInteger)
+        map(f, wr.val) ** wr.exponent
+      sy := retract(p)@Symbol
+      setPredicates(sy::Pattern(S), copy predicates p)
+
+@
+<<PATTERN2.dotabb>>=
+"PATTERN2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PATTERN2"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PATTERN2" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PATMATCH PatternMatch}
+\pagehead{PatternMatch}{PATMATCH}
+\pagepic{ps/v104patternmatch.ps}{PATMATCH}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PATMATCH PatternMatch>>=
+)abbrev package PATMATCH PatternMatch
+++ Top-level pattern matching functions
+++ Author: Manuel Bronstein
+++ Date Created: 3 Dec 1989
+++ Date Last Updated: 29 Jun 1990
+++ Description:
+++   This package provides the top-level pattern macthing functions.
+++ Keywords: pattern, matching.
+PatternMatch(Base, Subject, Pat): Exports == Implementation where
+  Base   : SetCategory
+  Subject: PatternMatchable Base
+  Pat    : ConvertibleTo Pattern Base
+
+  Exports ==> with
+    is?: (Subject, Pat)      -> Boolean
+      ++ is?(expr, pat) tests if the expression expr matches
+      ++ the pattern pat.
+    is?: (List Subject, Pat) -> Boolean
+      ++ is?([e1,...,en], pat) tests if the list of
+      ++ expressions \spad{[e1,...,en]} matches
+      ++ the pattern pat.
+    Is : (List Subject, Pat) ->
+                     PatternMatchListResult(Base, Subject, List Subject)
+      ++ Is([e1,...,en], pat) matches the pattern pat on the list of
+      ++ expressions \spad{[e1,...,en]} and returns the result.
+    if Subject has RetractableTo(Symbol) then
+      Is: (Subject, Pat) -> List Equation Subject
+        ++ Is(expr, pat) matches the pattern pat on the expression
+        ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
+        ++ returns an empty list if either expr is exactly equal to
+        ++ pat or if pat does not match expr.
+    else
+      if Subject has Ring then
+        Is: (Subject, Pat) -> List Equation Polynomial Subject
+          ++ Is(expr, pat) matches the pattern pat on the expression
+          ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
+          ++ returns an empty list if either expr is exactly equal to
+          ++ pat or if pat does not match expr.
+      else
+        Is: (Subject, Pat) -> PatternMatchResult(Base, Subject)
+          ++ Is(expr, pat) matches the pattern pat on the expression
+          ++ expr and returns a match of the form \spad{[v1 = e1,...,vn = en]};
+          ++ returns an empty match if expr is exactly equal to pat.
+          ++ returns a \spadfun{failed} match if pat does not match expr.
+
+  Implementation ==> add
+    import PatternMatchListAggregate(Base, Subject, List Subject)
+
+    ist: (Subject, Pat) -> PatternMatchResult(Base, Subject)
+
+    ist(s, p)                  == patternMatch(s, convert p, new())
+    is?(s:     Subject, p:Pat) == not failed? ist(s, p)
+    is?(s:List Subject, p:Pat) == not failed? Is(s, p)
+    Is(s:List Subject,  p:Pat) == patternMatch(s, convert p, new())
+
+    if Subject has RetractableTo(Symbol) then
+      Is(s:Subject, p:Pat):List(Equation Subject) ==
+        failed?(r := ist(s, p)) => empty()
+        [rec.key::Subject = rec.entry for rec in destruct r]
+
+    else
+      if Subject has Ring then
+        Is(s:Subject, p:Pat):List(Equation Polynomial Subject) ==
+          failed?(r := ist(s, p)) => empty()
+          [rec.key::Polynomial(Subject) =$Equation(Polynomial Subject)
+           rec.entry::Polynomial(Subject) for rec in destruct r]
+
+      else
+        Is(s:Subject,p:Pat):PatternMatchResult(Base,Subject) == ist(s,p)
+
+@
+<<PATMATCH.dotabb>>=
+"PATMATCH" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PATMATCH"]
+"PATMAB" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PATMAB"]
+"RETRACT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=RETRACT"]
+"LMODULE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=LMODULE"]
+"SGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=SGROUP"]
+"PATMATCH" -> "PATMAB"
+"PATMATCH" -> "RETRACT"
+"PATMATCH" -> "LMODULE"
+"PATMATCH" -> "SGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PMASS PatternMatchAssertions}
 \pagehead{PatternMatchAssertions}{PMASS}
 \pagepic{ps/v104patternmatchassertions.ps}{PMASS}{1.00}
@@ -57069,6 +59494,188 @@ PatternMatchAssertions(): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMFS PatternMatchFunctionSpace}
+\pagehead{PatternMatchFunctionSpace}{PMFS}
+\pagepic{ps/v104patternmatchfunctionspace.ps}{PMFS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMFS PatternMatchFunctionSpace>>=
+)abbrev package PMFS PatternMatchFunctionSpace
+++ Pattern matching on function spaces
+++ Author: Manuel Bronstein
+++ Date Created: 15 Mar 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++  This package provides pattern matching functions on function spaces.
+++ Keywords: pattern, matching, function, space.
+PatternMatchFunctionSpace(S, R, F): Exports== Implementation where
+  S: SetCategory
+  R: Join(IntegralDomain, OrderedSet, PatternMatchable S)
+  F: Join(FunctionSpace R, ConvertibleTo Pattern S, PatternMatchable S,
+          RetractableTo Kernel %)  -- that one is redundant but won't
+                                   -- compile without it
+
+  N   ==> NonNegativeInteger
+  K   ==> Kernel F
+  PAT ==> Pattern S
+  PRS ==> PatternMatchResult(S, F)
+  RCP ==> Record(val:PAT, exponent:N)
+  RCX ==> Record(var:K, exponent:Integer)
+
+  Exports ==> with
+    patternMatch: (F, PAT, PRS) -> PRS
+      ++ patternMatch(expr, pat, res) matches the pattern pat to the
+      ++ expression expr; res contains the variables of pat which
+      ++ are already matched and their matches.
+
+  Implementation ==> add
+    import PatternMatchKernel(S, F)
+    import PatternMatchTools(S, R, F)
+    import PatternMatchPushDown(S, R, F)
+
+    patternMatch(x, p, l) ==
+      generic? p => addMatch(p, x, l)
+      (r := retractIfCan(x)@Union(R, "failed")) case R =>
+        patternMatch(r::R, p, l)
+      (v := retractIfCan(x)@Union(K, "failed")) case K =>
+        patternMatch(v::K, p, l)
+      (q := isQuotient p) case Record(num:PAT, den:PAT) =>
+        uq := q::Record(num:PAT, den:PAT)
+        failed?(l := patternMatch(numer(x)::F, uq.num, l)) => l
+        patternMatch(denom(x)::F, uq.den, l)
+      (u := isPlus p) case List(PAT) =>
+        (lx := isPlus x) case List(F) =>
+          patternMatch(lx::List(F), u::List(PAT), +/#1, l, patternMatch)
+        (u := optpair(u::List(PAT))) case List(PAT) =>
+          failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
+          patternMatch(x, second(u::List(PAT)), l)
+        failed()
+      (u := isTimes p) case List(PAT) =>
+        (lx := isTimes x) case List(F) =>
+          patternMatchTimes(lx::List(F), u::List(PAT), l, patternMatch)
+        (u := optpair(u::List(PAT))) case List(PAT) =>
+          failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
+          patternMatch(x, second(u::List(PAT)), l)
+        failed()
+      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+        uur := uu::Record(val:PAT, exponent: PAT)
+        (ex := isExpt x) case RCX =>
+          failed?(l := patternMatch((ex::RCX).exponent::Integer::F,
+                                           uur.exponent, l)) => failed()
+          patternMatch((ex::RCX).var, uur.val, l)
+        optional?(uur.exponent) =>
+          failed?(l := addMatch(uur.exponent, 1, l)) => failed()
+          patternMatch(x, uur.val, l)
+        failed()
+      ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
+           (ex::RCX).exponent = ((ep::RCP).exponent)::Integer =>
+               patternMatch((ex::RCX).var, (ep::RCP).val, l)
+      failed()
+
+@
+<<PMFS.dotabb>>=
+"PMFS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMFS"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"PMFS" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMINS PatternMatchIntegerNumberSystem}
+\pagehead{PatternMatchIntegerNumberSystem}{PMINS}
+\pagepic{ps/v104patternmatchintegernumbersystem.ps}{PMINS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMINS PatternMatchIntegerNumberSystem>>=
+)abbrev package PMINS PatternMatchIntegerNumberSystem
+++ Pattern matching on integer number systems
+++ Author: Manuel Bronstein
+++ Date Created: 29 Nov 1989
+++ Date Last Updated: 22 Mar 1990
+++ Description:
+++   This package provides pattern matching functions on integers.
+++ Keywords: pattern, matching, integer.
+PatternMatchIntegerNumberSystem(I:IntegerNumberSystem): with
+  patternMatch: (I, Pattern Integer, PatternMatchResult(Integer, I)) ->
+                                          PatternMatchResult(Integer, I)
+    ++ patternMatch(n, pat, res) matches the pattern pat to the
+    ++ integer n; res contains the variables of pat which
+    ++ are already matched and their matches.
+ == add
+   import IntegerRoots(I)
+
+   PAT ==> Pattern Integer
+   PMR ==> PatternMatchResult(Integer, I)
+
+   patternMatchInner     : (I, PAT, PMR) -> PMR
+   patternMatchRestricted: (I, PAT, PMR, I) -> PMR
+   patternMatchSumProd   :
+     (I, List PAT, PMR, (I, I) -> Union(I, "failed"), I) -> PMR
+
+   patternMatch(x, p, l) ==
+     generic? p => addMatch(p, x, l)
+     patternMatchInner(x, p, l)
+
+   patternMatchRestricted(x, p, l, y) ==
+     generic? p => addMatchRestricted(p, x, l, y)
+     patternMatchInner(x, p, l)
+
+   patternMatchSumProd(x, lp, l, invOp, ident) ==
+     #lp = 2 =>
+       p2 := last lp
+       if ((r:= retractIfCan(p1 := first lp)@Union(Integer,"failed"))
+                          case "failed") then (p1 := p2; p2 := first lp)
+       (r := retractIfCan(p1)@Union(Integer, "failed")) case "failed" =>
+                                                                failed()
+       (y := invOp(x, r::Integer::I)) case "failed" => failed()
+       patternMatchRestricted(y::I, p2, l, ident)
+     failed()
+
+   patternMatchInner(x, p, l) ==
+     constant? p =>
+       (r := retractIfCan(p)@Union(Integer, "failed")) case Integer =>
+         convert(x)@Integer = r::Integer => l
+         failed()
+       failed()
+     (u := isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
+       ur := u::Record(val:PAT, exponent:NonNegativeInteger)
+       (v := perfectNthRoot(x, ur.exponent)) case "failed" => failed()
+       patternMatchRestricted(v::I, ur.val, l, 1)
+     (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+       uur := uu::Record(val:PAT, exponent: PAT)
+       pr := perfectNthRoot x
+       failed?(l := patternMatchRestricted(pr.exponent::Integer::I,
+                                         uur.exponent, l,1)) => failed()
+       patternMatchRestricted(pr.base, uur.val, l, 1)
+     (w := isTimes p) case List(PAT) =>
+       patternMatchSumProd(x, w::List(PAT), l, #1 exquo #2, 1)
+     (w := isPlus p) case List(PAT) =>
+      patternMatchSumProd(x,w::List(PAT),l,(#1-#2)::Union(I,"failed"),0)
+     (uv := isQuotient p) case Record(num:PAT, den:PAT) =>
+       uvr := uv::Record(num:PAT, den:PAT)
+       (r := retractIfCan(uvr.num)@Union(Integer,"failed")) case Integer
+         and (v := r::Integer::I exquo x) case I =>
+           patternMatchRestricted(v::I, uvr.den, l, 1)
+       (r := retractIfCan(uvr.den)@Union(Integer,"failed")) case Integer
+         => patternMatch(r::Integer * x, uvr.num, l)
+       failed()
+     failed()
+
+@
+<<PMINS.dotabb>>=
+"PMINS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMINS"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"FLAGG-" [color="#88FF44",href="bookvol10.3.pdf#nameddest=FLAGG"]
+"PMINS" -> "FLAGG"
+"PMINS" -> "FLAGG-"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package INTPM PatternMatchIntegration}
 \pagehead{PatternMatchIntegration}{INTPM}
 \pagepic{ps/v104patternmatchintegration.ps}{INTPM}{1.00}
@@ -57402,6 +60009,1367 @@ PatternMatchIntegration(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMKERNEL PatternMatchKernel}
+\pagehead{PatternMatchKernel}{PMKERNEL}
+\pagepic{ps/v104patternmatchkernel.ps}{PMKERNEL}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMKERNEL PatternMatchKernel>>=
+)abbrev package PMKERNEL PatternMatchKernel
+++ Pattern matching on kernels
+++ Author: Manuel Bronstein
+++ Date Created: 12 Jan 1990
+++ Date Last Updated: 4 May 1992
+++ Description:
+++   This package provides pattern matching functions on kernels.
+++ Keywords: pattern, matching, kernel.
+PatternMatchKernel(S, E): Exports == Implementation where
+  S: SetCategory
+  E: Join(OrderedSet, RetractableTo Kernel %,
+          ConvertibleTo Pattern S, PatternMatchable S)
+
+  PAT ==> Pattern S
+  PRS ==> PatternMatchResult(S, E)
+  POWER ==> "%power"::Symbol
+  NTHRT ==> "nthRoot"::Symbol
+
+  Exports ==> with
+    patternMatch: (Kernel E, PAT, PRS) -> PRS
+      ++ patternMatch(f(e1,...,en), pat, res) matches the pattern pat
+      ++ to \spad{f(e1,...,en)}; res contains the variables of pat which
+      ++ are already matched and their matches.
+
+  Implementation ==> add
+    patternMatchArg  : (List E, List PAT, PRS) -> PRS
+    patternMatchInner: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
+
+    -- matches the ordered lists ls and lp.
+    patternMatchArg(ls, lp, l) ==
+      #ls ^= #lp => failed()
+      for p in lp for s in ls repeat
+        generic? p and failed?(l := addMatch(p,s,l)) => return failed()
+      for p in lp for s in ls repeat
+        not(generic? p) and failed?(l := patternMatch(s, p, l)) =>
+                                                         return failed()
+      l
+
+    patternMatchInner(s, p, l) ==
+      generic? p => addMatch(p, s::E, l)
+      (u := isOp p) case Record(op:BasicOperator, arg: List PAT) =>
+        ur := u::Record(op:BasicOperator, arg: List PAT)
+        ur.op = operator s => patternMatchArg(argument s, ur.arg, l)
+        failed()
+      constant? p =>
+        ((v := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
+          and ((w := symbolIfCan s) case Symbol) and
+            (v::Symbol = w::Symbol) => l
+        failed()
+      "failed"
+
+    if E has Monoid then
+      patternMatchMonoid: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
+      patternMatchOpt   : (E, List PAT, PRS, E) -> PRS
+
+      patternMatchOpt(x, lp, l, id) ==
+        (u := optpair lp) case List(PAT) =>
+          failed?(l := addMatch(first(u::List(PAT)), id, l)) => failed()
+          patternMatch(x, second(u::List(PAT)), l)
+        failed()
+
+      patternMatchMonoid(s, p, l) ==
+        (u := patternMatchInner(s, p, l)) case PRS => u::PRS
+        (v := isPower p) case Record(val:PAT, exponent:PAT) =>
+          vr := v::Record(val:PAT, exponent: PAT)
+          is?(op := operator s, POWER) =>
+            patternMatchArg(argument s, [vr.val, vr.exponent], l)
+          is?(op,NTHRT) and ((r := recip(second(arg := argument s))) case E) =>
+            patternMatchArg([first arg, r::E], [vr.val, vr.exponent], l)
+          optional?(vr.exponent) =>
+            failed?(l := addMatch(vr.exponent, 1, l)) => failed()
+            patternMatch(s::E, vr.val, l)
+          failed()
+        (w := isTimes p) case List(PAT) =>
+          patternMatchOpt(s::E, w::List(PAT), l, 1)
+        "failed"
+
+      if E has AbelianMonoid then
+        patternMatch(s, p, l) ==
+          (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
+          (w := isPlus p) case List(PAT) =>
+            patternMatchOpt(s::E, w::List(PAT), l, 0)
+          failed()
+
+      else
+        patternMatch(s, p, l) ==
+          (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
+          failed()
+
+    else
+      patternMatch(s, p, l) ==
+        (u := patternMatchInner(s, p, l)) case PRS => u::PRS
+        failed()
+
+@
+<<PMKERNEL.dotabb>>=
+"PMKERNEL" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMKERNEL"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"PMKERNEL" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMLSAGG PatternMatchListAggregate}
+\pagehead{PatternMatchListAggregate}{PMLSAGG}
+\pagepic{ps/v104patternmatchlistaggregate.ps}{PMLSAGG}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMLSAGG PatternMatchListAggregate>>=
+)abbrev package PMLSAGG PatternMatchListAggregate
+++ Pattern matching for list aggregates
+++ Author: Manuel Bronstein
+++ Date Created: 4 Dec 1989
+++ Date Last Updated: 29 Jun 1990
+++ Description:
+++   This package provides pattern matching functions on lists.
+++ Keywords: pattern, matching, list.
+PatternMatchListAggregate(S, R, L): Exports == Implementation where
+  S: SetCategory
+  R: PatternMatchable S
+  L: ListAggregate R
+
+  PLR ==> PatternMatchListResult(S, R, L)
+
+  Exports ==> with
+    patternMatch: (L, Pattern S, PLR) -> PLR
+      ++ patternMatch(l, pat, res) matches the pattern pat to the
+      ++ list l; res contains the variables of pat which
+      ++ are already matched and their matches.
+
+  Implementation ==> add
+    match: (L, List Pattern S, PLR, Boolean) -> PLR
+
+    patternMatch(l, p, r) ==
+      (u := isList p) case "failed" => failed()
+      match(l, u::List Pattern S, r, true)
+
+    match(l, lp, r, new?) ==
+      empty? lp =>
+        empty? l => r
+        failed()
+      multiple?(p0 := first lp) =>
+        empty? rest lp =>
+          if not new? then l := reverse_! l
+          makeResult(atoms r, addMatchRestricted(p0,l,lists r,empty()))
+        new? => match(reverse l, reverse lp, r, false)
+        error "Only one multiple pattern allowed in list"
+      empty? l => failed()
+      failed?(r := makeResult(patternMatch(first l,p0,atoms r),lists r))
+                                                             => failed()
+      match(rest l, rest lp, r, new?)
+
+@
+<<PMLSAGG.dotabb>>=
+"PMLSAGG" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMLSAGG"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PMLSAGG" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMPLCAT PatternMatchPolynomialCategory}
+\pagehead{PatternMatchPolynomialCategory}{PMPLCAT}
+\pagepic{ps/v104patternmatchpolynomialcategory.ps}{PMPLCAT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMPLCAT PatternMatchPolynomialCategory>>=
+)abbrev package PMPLCAT PatternMatchPolynomialCategory
+++ Pattern matching on polynomial objects
+++ Author: Manuel Bronstein
+++ Date Created: 9 Jan 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++   This package provides pattern matching functions on polynomials.
+++ Keywords: pattern, matching, polynomial.
+PatternMatchPolynomialCategory(S,E,V,R,P):Exports== Implementation where
+  S: SetCategory
+  E: OrderedAbelianMonoidSup
+  V: OrderedSet
+  R: Join(Ring, OrderedSet, PatternMatchable S)
+  P: Join(PolynomialCategory(R, E, V), ConvertibleTo Pattern S)
+
+  N   ==> NonNegativeInteger
+  PAT ==> Pattern S
+  PRS ==> PatternMatchResult(S, P)
+  RCP ==> Record(val:PAT, exponent:N)
+  RCX ==> Record(var:V, exponent:N)
+
+  Exports ==> with
+    patternMatch: (P, PAT, PRS, (V, PAT, PRS) -> PRS) -> PRS
+      ++ patternMatch(p, pat, res, vmatch) matches the pattern pat to
+      ++ the polynomial p. res contains the variables of pat which
+      ++ are already matched and their matches; vmatch is the matching
+      ++ function to use on the variables.
+      -- This can be more efficient than pushing down when the variables
+      -- are recursive over P (e.g. kernels)
+    if V has PatternMatchable S then
+      patternMatch: (P, PAT, PRS) -> PRS
+        ++ patternMatch(p, pat, res) matches the pattern pat to
+        ++ the polynomial p; res contains the variables of pat which
+        ++ are already matched and their matches.
+
+  Implementation ==> add
+    import PatternMatchTools(S, R, P)
+    import PatternMatchPushDown(S, R, P)
+
+    if V has PatternMatchable S then
+      patternMatch(x, p, l) ==
+        patternMatch(x, p, l, patternMatch$PatternMatchPushDown(S,V,P))
+
+    patternMatch(x, p, l, vmatch) ==
+      generic? p => addMatch(p, x, l)
+      (r := retractIfCan(x)@Union(R, "failed")) case R =>
+        patternMatch(r::R, p, l)
+      (v := retractIfCan(x)@Union(V, "failed")) case V =>
+        vmatch(v::V, p, l)
+      (u := isPlus p) case List(PAT) =>
+        (lx := isPlus x) case List(P) =>
+          patternMatch(lx::List(P), u::List(PAT), +/#1, l,
+                                       patternMatch(#1, #2, #3, vmatch))
+        (u := optpair(u::List(PAT))) case List(PAT) =>
+          failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
+          patternMatch(x, second(u::List(PAT)), l, vmatch)
+        failed()
+      (u := isTimes p) case List(PAT) =>
+        (lx := isTimes x) case List(P) =>
+          patternMatchTimes(lx::List(P), u::List(PAT), l,
+                                       patternMatch(#1, #2, #3, vmatch))
+        (u := optpair(u::List(PAT))) case List(PAT) =>
+          failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
+          patternMatch(x, second(u::List(PAT)), l, vmatch)
+        failed()
+      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+        uur := uu::Record(val:PAT, exponent: PAT)
+        (ex := isExpt x) case RCX =>
+          failed?(l := patternMatch((ex::RCX).exponent::Integer::P,
+                                   uur.exponent, l, vmatch)) => failed()
+          vmatch((ex::RCX).var, uur.val, l)
+        optional?(uur.exponent) =>
+          failed?(l := addMatch(uur.exponent, 1, l)) => failed()
+          patternMatch(x, uur.val, l, vmatch)
+        failed()
+      ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
+           (ex::RCX).exponent = (ep::RCP).exponent =>
+               vmatch((ex::RCX).var, (ep::RCP).val, l)
+      failed()
+
+@
+<<PMPLCAT.dotabb>>=
+"PMPLCAT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMPLCAT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PMPLCAT" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMDOWN PatternMatchPushDown}
+\pagehead{PatternMatchPushDown}{PMDOWN}
+\pagepic{ps/v104patternmatchpushdown.ps}{PMDOWN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMDOWN PatternMatchPushDown>>=
+)abbrev package PMDOWN PatternMatchPushDown
+++ Pattern matching in towers
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 16 August 1995
+++ Description:
+++   This packages provides tools for matching recursively
+++   in type towers.
+++ Keywords: pattern, matching, quotient, field.
+PatternMatchPushDown(S, A, B): Exports == Implementation where
+  S: SetCategory
+  A: PatternMatchable S
+  B: Join(SetCategory, RetractableTo A)
+
+  PAT ==> Pattern S
+  PRA ==> PatternMatchResult(S, A)
+  PRB ==> PatternMatchResult(S, B)
+  REC ==> Record(pat:PAT, res:PRA)
+
+  Exports ==> with
+    fixPredicate: (B -> Boolean) -> (A -> Boolean)
+      ++ fixPredicate(f) returns g defined by g(a) = f(a::B);
+    patternMatch: (A, PAT, PRB)  -> PRB
+      ++ patternMatch(expr, pat, res) matches the pattern pat to the
+      ++ expression expr; res contains the variables of pat which
+      ++ are already matched and their matches.
+      ++ Note: this function handles type towers by changing the predicates
+      ++ and calling the matching function provided by \spad{A}.
+
+  Implementation ==> add
+    import PatternMatchResultFunctions2(S, A, B)
+
+    fixPred      : Any -> Union(Any, "failed")
+    inA          : (PAT, PRB) -> Union(List A, "failed")
+    fixPredicates: (PAT, PRB, PRA) -> Union(REC, "failed")
+    fixList:(List PAT -> PAT, List PAT, PRB, PRA) -> Union(REC,"failed")
+
+    fixPredicate f == f(#1::B)
+
+    patternMatch(a, p, l) ==
+      (u := fixPredicates(p, l, new())) case "failed" => failed()
+      union(l, map(#1::B, patternMatch(a, (u::REC).pat, (u::REC).res)))
+
+    inA(p, l) ==
+      (u := getMatch(p, l)) case "failed" => empty()
+      (r := retractIfCan(u::B)@Union(A, "failed")) case A => [r::A]
+      "failed"
+
+    fixList(fn, l, lb, la) ==
+      ll:List(PAT) := empty()
+      for x in l repeat
+        (f := fixPredicates(x, lb, la)) case "failed" => return "failed"
+        ll := concat((f::REC).pat, ll)
+        la := (f::REC).res
+      [fn ll, la]
+
+    fixPred f ==
+      (u:= retractIfCan(f)$AnyFunctions1(B -> Boolean)) case "failed" =>
+                                                                "failed"
+      g := fixPredicate(u::(B -> Boolean))
+      coerce(g)$AnyFunctions1(A -> Boolean)
+
+    fixPredicates(p, lb, la) ==
+      (r:=retractIfCan(p)@Union(S,"failed")) case S or quoted? p =>[p,la]
+      (u := isOp p) case Record(op:BasicOperator, arg:List PAT) =>
+        ur := u::Record(op:BasicOperator, arg:List PAT)
+        fixList((ur.op) #1, ur.arg, lb, la)
+      (us := isPlus p) case List(PAT) =>
+        fixList(reduce("+", #1), us::List(PAT), lb, la)
+      (us := isTimes p) case List(PAT) =>
+        fixList(reduce("*", #1), us::List(PAT), lb, la)
+      (v := isQuotient p) case Record(num:PAT, den:PAT) =>
+        vr := v::Record(num:PAT, den:PAT)
+        (fn := fixPredicates(vr.num, lb, la)) case "failed" => "failed"
+        la  := (fn::REC).res
+        (fd := fixPredicates(vr.den, lb, la)) case "failed" => "failed"
+        [(fn::REC).pat / (fd::REC).pat, (fd::REC).res]
+      (w:= isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
+        wr := w::Record(val:PAT, exponent: NonNegativeInteger)
+        (f := fixPredicates(wr.val, lb, la)) case "failed" => "failed"
+        [(f::REC).pat ** wr.exponent, (f::REC).res]
+      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+        uur := uu::Record(val:PAT, exponent: PAT)
+        (fv := fixPredicates(uur.val, lb, la)) case "failed" => "failed"
+        la  := (fv::REC).res
+        (fe := fixPredicates(uur.exponent, lb, la)) case "failed" =>
+          "failed"
+        [(fv::REC).pat ** (fe::REC).pat, (fe::REC).res]
+      generic? p =>
+        (ua := inA(p, lb)) case "failed" => "failed"
+        lp := [if (h := fixPred g) case Any then h::Any else
+                        return "failed" for g in predicates p]$List(Any)
+        q := setPredicates(patternVariable(retract p, constant? p,
+                                           optional? p, multiple? p), lp)
+        [q, (empty?(ua::List A) => la; insertMatch(q,first(ua::List A), la))]
+      error "Should not happen"
+
+@
+<<PMDOWN.dotabb>>=
+"PMDOWN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMDOWN"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PMDOWN" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMQFCAT PatternMatchQuotientFieldCategory}
+\pagehead{PatternMatchQuotientFieldCategory}{PMQFCAT}
+\pagepic{ps/v104patternmatchquotientfieldcategory.ps}{PMQFCAT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMQFCAT PatternMatchQuotientFieldCategory>>=
+)abbrev package PMQFCAT PatternMatchQuotientFieldCategory
+++ Pattern matching on quotient objects
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 20 June 1991
+++ Description:
+++   This package provides pattern matching functions on quotients.
+++ Keywords: pattern, matching, quotient, field.
+PatternMatchQuotientFieldCategory(S,R,Q):Exports == Implementation where
+  S: SetCategory
+  R: Join(IntegralDomain, PatternMatchable S, ConvertibleTo Pattern S)
+  Q: QuotientFieldCategory R
+
+  PAT ==> Pattern S
+  PRQ ==> PatternMatchResult(S, Q)
+
+  Exports ==> with
+    patternMatch: (Q, PAT, PRQ) -> PRQ
+      ++ patternMatch(a/b, pat, res) matches the pattern pat to the
+      ++ quotient a/b; res contains the variables of pat which
+      ++ are already matched and their matches.
+
+  Implementation ==> add
+    import PatternMatchPushDown(S, R, Q)
+
+    patternMatch(x, p, l) ==
+      generic? p => addMatch(p, x, l)
+      (r := retractIfCan x)@Union(R, "failed") case R =>
+        patternMatch(r::R, p, l)
+      (u := isQuotient p) case Record(num:PAT, den:PAT) =>
+        ur := u::Record(num:PAT, den:PAT)
+        failed?(l := patternMatch(numer x, ur.num, l)) => l
+        patternMatch(denom x, ur.den, l)
+      failed()
+
+@
+<<PMQFCAT.dotabb>>=
+"PMQFCAT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMQFCAT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PMQFCAT" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PATRES2 PatternMatchResultFunctions2}
+\pagehead{PatternMatchResultFunctions2}{PATRES2}
+\pagepic{ps/v104patternmatchresultfunctions2.ps}{PATRES2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PATRES2 PatternMatchResultFunctions2>>=
+)abbrev package PATRES2 PatternMatchResultFunctions2
+++ Lifts maps to pattern matching results
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 14 Dec 1989
+++ Description: Lifts maps to pattern matching results.
+++ Keywords: pattern, matching.
+PatternMatchResultFunctions2(R, A, B): Exports == Implementation where
+  R: SetCategory
+  A: SetCategory
+  B: SetCategory
+
+  Exports ==> with
+    map: (A -> B, PatternMatchResult(R, A)) -> PatternMatchResult(R, B)
+      ++ map(f, [(v1,a1),...,(vn,an)]) returns the matching result
+      ++ [(v1,f(a1)),...,(vn,f(an))].
+
+  Implementation ==> add
+    map(f, r) ==
+      failed? r => failed()
+      construct [[rec.key, f(rec.entry)] for rec in destruct r]
+
+@
+<<PATRES2.dotabb>>=
+"PATRES2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PATRES2"]
+"BASTYPE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=BASTYPE"]
+"KOERCE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=KOERCE"]
+"PATRES2" -> "BASTYPE"
+"PATRES2" -> "KOERCE"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMSYM PatternMatchSymbol}
+\pagehead{PatternMatchSymbol}{PMSYM}
+\pagepic{ps/v104patternmatchsymbol.ps}{PMSYM}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMSYM PatternMatchSymbol>>=
+)abbrev package PMSYM PatternMatchSymbol
+++ Pattern matching on symbols
+++ Author: Manuel Bronstein
+++ Date Created: 9 Jan 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++   This package provides pattern matching functions on symbols.
+++ Keywords: pattern, matching, symbol.
+PatternMatchSymbol(S:SetCategory): with
+  patternMatch: (Symbol, Pattern S, PatternMatchResult(S, Symbol)) ->
+                                           PatternMatchResult(S, Symbol)
+    ++ patternMatch(expr, pat, res) matches the pattern pat to the
+    ++ expression expr; res contains the variables of pat which
+    ++ are already matched and their matches (necessary for recursion).
+ == add
+  import TopLevelPatternMatchControl
+
+  patternMatch(s, p, l) ==
+    generic? p  => addMatch(p, s, l)
+    constant? p =>
+      ((u := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
+        and (u::Symbol) = s => l
+      failed()
+    failed()
+
+@
+<<PMSYM.dotabb>>=
+"PMSYM" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMSYM"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"PMSYM" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PMTOOLS PatternMatchTools}
+\pagehead{PatternMatchTools}{PMTOOLS}
+\pagepic{ps/v104patternmatchtools.ps}{PMTOOLS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PMTOOLS PatternMatchTools>>=
+)abbrev package PMTOOLS PatternMatchTools
+++ Tools for the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 13 Mar 1990
+++ Date Last Updated: 4 February 1992
+++ Description:
+++   This package provides tools for the pattern matcher.
+++ Keywords: pattern, matching, tools.
+PatternMatchTools(S, R, P): Exports == Implementation where
+  S: SetCategory
+  R: Join(Ring, OrderedSet)
+  P: Join(Ring, ConvertibleTo Pattern S, RetractableTo R)
+
+  PAT ==> Pattern S
+  PRS ==> PatternMatchResult(S, P)
+  REC ==> Record(res:PRS, s:List P)
+  RC  ==> Record(pat:List PAT, s:List P)
+
+  Exports ==> with
+    patternMatch: (List P, List PAT, List P -> P, PRS,
+                                            (P, PAT, PRS) -> PRS) -> PRS
+      ++ patternMatch(lsubj, lpat, op, res, match) matches the list
+      ++ of patterns lpat to the list of subjects lsubj, allowing for
+      ++ commutativity; op is the operator such that op(lpat) should
+      ++ match op(lsubj) at the end, r contains the previous matches,
+      ++ and match is a pattern-matching function on P.
+    patternMatchTimes: (List P, List PAT, PRS,
+                                            (P, PAT, PRS) -> PRS) -> PRS
+      ++ patternMatchTimes(lsubj, lpat, res, match) matches the
+      ++ product of patterns \spad{reduce(*,lpat)}
+      ++ to the product of subjects \spad{reduce(*,lsubj)};
+      ++ r contains the previous matches
+      ++ and match is a pattern-matching function on P.
+
+  Implementation ==> add
+    import PatternFunctions1(S, P)
+
+    preprocessList: (PAT, List P, PRS) -> Union(List P, "failed")
+    selBestGen    : List PAT -> List PAT
+    negConstant   : List P -> Union(P, "failed")
+    findMatch     : (PAT, List P, PRS, P, (P, PAT, PRS) -> PRS) -> REC
+    tryToMatch    : (List PAT, REC, P, (P, PAT, PRS) -> PRS) ->
+                                                  Union(REC, "failed")
+    filterMatchedPatterns: (List PAT, List P, PRS) -> Union(RC, "failed")
+
+    mn1 := convert(-1::P)@Pattern(S)
+
+    negConstant l ==
+      for x in l repeat
+        ((r := retractIfCan(x)@Union(R, "failed")) case R) and
+          (r::R < 0) => return x
+      "failed"
+
+-- tries to match the list of patterns lp to the list of subjects rc.s
+-- with rc.res being the list of existing matches.
+-- updates rc with the new result and subjects still to match
+    tryToMatch(lp, rc, ident, pmatch) ==
+      rec:REC := [l := rc.res, ls := rc.s]
+      for p in lp repeat
+        rec := findMatch(p, ls, l, ident, pmatch)
+        failed?(l := rec.res) => return "failed"
+        ls := rec.s
+      rec
+
+-- handles -1 in the pattern list.
+    patternMatchTimes(ls, lp, l, pmatch) ==
+      member?(mn1, lp) =>
+        (u := negConstant ls) case "failed" => failed()
+        if (u::P ^= -1::P) then ls := concat(-u::P, ls)
+        patternMatch(remove(u::P,ls), remove(mn1,lp), */#1, l, pmatch)
+      patternMatch(ls, lp, */#1, l, pmatch)
+
+-- finds a match for p in ls, try not to match to a "bad" value
+    findMatch(p, ls, l, ident, pmatch) ==
+      bad:List(P) :=
+        generic? p => setIntersection(badValues p, ls)
+        empty()
+      l1:PRS := failed()
+      for x in setDifference(ls, bad)
+        while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
+      failed? l1 =>
+        for x in bad
+          while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
+        failed? l1 => [addMatchRestricted(p, ident, l, ident), ls]
+        [l1, remove(t, ls)]
+      [l1, remove(t, ls)]
+
+-- filters out pattern if it's generic and already matched.
+    preprocessList(pattern, ls, l) ==
+      generic? pattern =>
+        (u := getMatch(pattern, l)) case P =>
+          member?(u::P, ls) => [u::P]
+          "failed"
+        empty()
+      empty()
+
+-- take out already matched generic patterns
+    filterMatchedPatterns(lp, ls, l) ==
+      for p in lp repeat
+        (rc := preprocessList(p, ls, l)) case "failed" => return "failed"
+        if not empty?(rc::List(P)) then
+          lp := remove(p,  lp)
+          ls := remove(first(rc::List(P)), ls)
+      [lp, ls]
+
+-- select a generic pattern with no predicate if possible
+    selBestGen l ==
+      ans := empty()$List(PAT)
+      for p in l | generic? p repeat
+        ans := [p]
+        not hasPredicate? p => return ans
+      ans
+
+-- matches unordered lists ls and lp
+    patternMatch(ls, lp, op, l, pmatch) ==
+      ident := op empty()
+      (rc := filterMatchedPatterns(lp, ls, l)) case "failed" => return failed()
+      lp := (rc::RC).pat
+      ls := (rc::RC).s
+      empty? lp => l
+      #(lpm := select(optional?, lp)) > 1 =>
+        error "More than one optional pattern in sum/product"
+      (#ls + #lpm) < #lp => failed()
+      if (not empty? lpm) and (#ls + 1 = #lp) then
+        lp := remove(first lpm, lp)
+        failed?(l := addMatch(first lpm, ident, l)) => return l
+      #(lpm := select(multiple?, lp)) > 1 =>
+        error "More than one expandable pattern in sum/product"
+      #ls > #lp and empty? lpm and empty?(lpm := selBestGen lp) =>
+        failed()
+      if not empty? lpm then lp := remove(first lpm, lp)
+      -- this is the order in which we try to match predicates
+      -- l1 = constant patterns (i.e. 'x, or sin('x))
+      l1 := select(constant?, lp)
+      -- l2 = patterns with a predicate attached to them
+      l2 := select(hasPredicate? #1 and not constant? #1, lp)
+      -- l3 = non-generic patterns without predicates
+      l3 := sort_!(depth(#1) > depth(#2),
+        select(not(hasPredicate? #1 or generic? #1 or constant? #1),lp))
+      -- l4 = generic patterns with predicates
+      l4 := select(generic? #1 and
+                              not(hasPredicate? #1 or constant? #1), lp)
+      rec:REC := [l, ls]
+      (u := tryToMatch(l1, rec, ident, pmatch)) case "failed" =>
+        failed()
+      (u := tryToMatch(l2, u::REC, ident, pmatch)) case "failed" =>
+        failed()
+      (u := tryToMatch(l3, u::REC, ident, pmatch)) case "failed" =>
+        failed()
+      rec := u::REC
+      (rc := filterMatchedPatterns(l4,rec.s,rec.res)) case "failed" => failed()
+      rec := [rec.res, (rc::RC).s]
+      (u := tryToMatch((rc::RC).pat,rec,ident,pmatch)) case "failed" => failed()
+      rec := u::REC
+      l := rec.res
+      ls := rec.s
+      empty? lpm =>
+        empty? ls => l
+        failed()
+      addMatch(first lpm, op ls, l)
+
+@
+<<PMTOOLS.dotabb>>=
+"PMTOOLS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PMTOOLS"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PMTOOLS" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PERMAN Permanent}
+<<Permanent.input>>=
+-- perman.spad.pamphlet Permanent.input
+)spool Permanent.output
+)set message test on
+)set message auto off
+)clear all
+--S 1 of 3
+kn n ==
+  r : MATRIX INT := new(n,n,1)
+  for i in 1..n repeat
+    r.i.i := 0
+  r
+--R 
+--R                                                                   Type: Void
+--E 1
+
+--S 2 of 3
+permanent(kn(5) :: SQMATRIX(5,INT))
+--R 
+--R   Compiling function kn with type PositiveInteger -> Matrix Integer 
+--R
+--R   (2)  44
+--R                                                        Type: PositiveInteger
+--E 2
+
+--S 3 of 3
+[permanent(kn(n) :: SQMATRIX(n,INT)) for n in 1..13]
+--R 
+--R   Cannot compile conversion for types involving local variables. In 
+--R      particular, could not compile the expression involving :: 
+--R      SQMATRIX(n,INT) 
+--R   AXIOM will attempt to step through and interpret the code.
+--R
+--R   (3)
+--R   [0,1,2,9,44,265,1854,14833,133496,1334961,14684570,176214841,2290792932]
+--R                                                Type: List NonNegativeInteger
+--E 3
+)spool
+)lisp (bye)
+@
+<<Permanent.help>>=
+====================================================================
+Permanent examples
+====================================================================
+
+The package Permanent provides the function permanent for square
+matrices.  The permanent of a square matrix can be computed in the
+same way as the determinant by expansion of minors except that for the
+permanent the sign for each element is 1, rather than being 1 if the
+row plus column indices is positive and -1 otherwise.  This function
+is much more difficult to compute efficiently than the determinant.
+An example of the use of permanent is the calculation of the n-th
+derangement number, defined to be the number of different possibilities 
+for n couples to dance but never with their own spouse.
+
+Consider an n by n matrix with entries 0 on the diagonal and 1 elsewhere.  
+Think of the rows as one-half of each couple (for example, the males) and 
+the columns the other half.  The permanent of such a matrix gives the 
+desired derangement number.
+
+  kn n ==
+    r : MATRIX INT := new(n,n,1)
+    for i in 1..n repeat
+      r.i.i := 0
+    r
+
+Here are some derangement numbers, which you see grow quite fast.
+
+  permanent(kn(5) :: SQMATRIX(5,INT))
+
+  [permanent(kn(n) :: SQMATRIX(n,INT)) for n in 1..13]
+
+See Also:
+o )show Permanent
+
+@
+\pagehead{Permanent}{PERMAN}
+\pagepic{ps/v104permanent.ps}{PERMAN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PERMAN Permanent>>=
+)abbrev package PERMAN Permanent
+++ Authors: Johannes Grabmeier, Oswald Gschnitzer
+++ Date Created: 7 August 1989
+++ Date Last Updated: 23 August 1990
+++ Basic Operations: permanent
+++ Related Constructors: GrayCode
+++ Also See: MatrixLinearAlgebraFunctions
+++ AMS Classifications:
+++ Keywords: permanent
+++ References:
+++  Henryk Minc: Evaluation of Permanents,
+++    Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
+++  Nijenhuis and Wilf : Combinatorical Algorithms, Academic
+++    Press, New York 1978.
+++  S.G.Williamson, Combinatorics for Computer Science,
+++    Computer Science Press, 1985.
+++ Description:
+++  Permanent implements the functions {\em permanent}, the 
+++  permanent for square matrices.
+Permanent(n : PositiveInteger, R : Ring with commutative("*")):
+ public == private where
+  I  ==> Integer
+  L  ==> List
+  V  ==> Vector
+  SM  ==> SquareMatrix(n,R)
+  VECTPKG1 ==> VectorPackage1(I)
+  NNI ==> NonNegativeInteger
+  PI ==> PositiveInteger
+  GRAY ==> GrayCode
+ 
+  public ==> with
+ 
+    permanent:  SM  -> R
+      ++ permanent(x) computes the permanent of a square matrix x.
+      ++ The {\em permanent} is equivalent to 
+      ++ the \spadfun{determinant} except that coefficients have 
+      ++ no change of sign. This function
+      ++ is much more difficult to compute than the 
+      ++ {\em determinant}. The formula used is by H.J. Ryser,
+      ++ improved by [Nijenhuis and Wilf, Ch. 19].
+      ++ Note: permanent(x) choose one of three algorithms, depending
+      ++ on the underlying ring R and on n, the number of rows (and
+      ++ columns) of x:\begin{items}
+      ++ \item 1. if 2 has an inverse in R we can use the algorithm of
+      ++    [Nijenhuis and Wilf, ch.19,p.158]; if 2 has no inverse,
+      ++    some modifications are necessary:
+      ++ \item 2. if {\em n > 6} and R is an integral domain with characteristic
+      ++    different from 2 (the algorithm works if and only 2 is not a
+      ++    zero-divisor of R and {\em characteristic()$R ^= 2},
+      ++    but how to check that for any given R ?),
+      ++    the local function {\em permanent2} is called;
+      ++ \item 3. else, the local function {\em permanent3} is called
+      ++    (works for all commutative rings R).
+      ++ \end{items}
+ 
+  private ==> add
+ 
+    -- local functions:
+ 
+    permanent2:  SM  -> R
+ 
+    permanent3:  SM  -> R
+ 
+    x : SM
+    a,b : R
+    i,j,k,l : I
+ 
+    permanent3(x) ==
+      -- This algorithm is based upon the principle of inclusion-
+      -- exclusion. A Gray-code is used to generate the subsets of
+      -- 1,... ,n. This reduces the number of additions needed in
+      -- every step.
+      sgn : R := 1
+      k : R
+      a := 0$R
+      vv : V V I := firstSubsetGray(n)$GRAY
+        -- For the meaning of the elements of vv, see GRAY.
+      w : V R := new(n,0$R)
+      j := 1   -- Will be the number of the element changed in subset
+      while j ^= (n+1) repeat  -- we sum over all subsets of (1,...,n)
+        sgn := -sgn
+        b := sgn
+        if vv.1.j = 1 then k := -1
+        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
+        for i in 1..(n::I) repeat
+          w.i :=  w.i +$R k *$R  x(i,j)
+          b := b *$R w.i
+        a := a +$R b
+        vv := nextSubsetGray(vv,n)$GRAY
+        j := vv.2.1
+      if odd?(n) then a := -a
+      a
+ 
+ 
+    permanent(x) ==
+      -- If 2 has an inverse in R, we can spare half of the calcu-
+      -- lation needed in "permanent3": This is the algorithm of
+      -- [Nijenhuis and Wilf, ch.19,p.158]
+      n = 1 => x(1,1)
+      two : R := (2:I) :: R
+      half : Union(R,"failed") := recip(two)
+      if (half case "failed") then
+        if n < 7 then return permanent3(x)
+        else return permanent2(x)
+      sgn : R := 1
+      a := 0$R
+      w : V R := new(n,0$R)
+      -- w.i will be at first x.i and later lambda.i in
+      -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
+      rowi : V R := new(n,0$R)
+      for i in 1..n repeat
+        rowi := row(x,i) :: V R
+        b := 0$R
+        for j in 1..n repeat
+          b := b + rowi.j
+        w.i := rowi(n) - (half*b)$R
+      vv : V V I := firstSubsetGray((n-1): PI)$GRAY
+       -- For the meaning of the elements of vv, see GRAY.
+      n :: I
+      b := 1
+      for i in 1..n repeat
+        b := b * w.i
+      a := a+b
+      j := 1   -- Will be the number of the element changed in subset
+      while j ^= n repeat  -- we sum over all subsets of (1,...,n-1)
+        sgn := -sgn
+        b := sgn
+        if vv.1.j = 1 then k := -1
+        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
+        for i in 1..n repeat
+          w.i :=  w.i +$R k *$R  x(i,j)
+          b := b *$R w.i
+        a := a +$R b
+        vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
+        j := vv.2.1
+      if not odd?(n) then a := -a
+      two * a
+ 
+    permanent2(x) ==
+      c : R := 0
+      sgn : R := 1
+      if (not (R has IntegralDomain))
+        -- or (characteristic()$R = (2:NNI))
+        -- compiler refuses to compile the line above !!
+        or  (sgn + sgn = c)
+      then return permanent3(x)
+      -- This is a slight modification of permanent which is
+      -- necessary if 2 is not zero or a zero-divisor in R, but has
+      -- no inverse in R.
+      n = 1 => x(1,1)
+      two : R := (2:I) :: R
+      a := 0$R
+      w : V R := new(n,0$R)
+      -- w.i will be at first x.i and later lambda.i in
+      -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
+      rowi : V R := new(n,0$R)
+      for i in 1..n repeat
+        rowi := row(x,i) :: V R
+        b := 0$R
+        for j in 1..n repeat
+          b := b + rowi.j
+        w.i := (two*(rowi(n)))$R - b
+      vv : V V I := firstSubsetGray((n-1): PI)$GRAY
+      n :: I
+      b := 1
+      for i in 1..n repeat
+        b := b *$R w.i
+      a := a +$R b
+      j := 1   -- Will be the number of the element changed in subset
+      while j ^= n repeat  -- we sum over all subsets of (1,...,n-1)
+        sgn := -sgn
+        b := sgn
+        if vv.1.j = 1 then k := -1
+        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
+        c := k * two
+        for i in 1..n repeat
+          w.i :=  w.i +$R c *$R x(i,j)
+          b := b *$R w.i
+        a := a +$R b
+        vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
+        j := vv.2.1
+      if not odd?(n) then a := -a
+      b := two ** ((n-1):NNI)
+      (a exquo b) :: R
+
+@
+<<PERMAN.dotabb>>=
+"PERMAN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PERMAN"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"PERMAN" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PGE PermutationGroupExamples}
+\pagehead{PermutationGroupExamples}{PGE}
+\pagepic{ps/v104permutationgroupexamples.ps}{PGE}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PGE PermutationGroupExamples>>=
+)abbrev package PGE PermutationGroupExamples
+++ Authors: M. Weller, G. Schneider, J. Grabmeier
+++ Date Created: 20 February 1990
+++ Date Last Updated: 09 June 1990
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++  J. Conway, R. Curtis, S. Norton, R. Parker, R. Wilson:
+++   Atlas of Finite Groups, Oxford, Clarendon Press, 1987
+++ Description: 
+++   PermutationGroupExamples provides permutation groups for
+++   some classes of groups: symmetric, alternating, dihedral, cyclic,
+++   direct products of cyclic, which are in fact the finite abelian groups
+++   of symmetric groups called Young subgroups.
+++   Furthermore, Rubik's group as permutation group of 48 integers and a list
+++   of sporadic simple groups derived from the atlas of finite groups.
+
+PermutationGroupExamples():public == private where
+
+    L          ==> List
+    I          ==> Integer
+    PI         ==> PositiveInteger
+    NNI        ==> NonNegativeInteger
+    PERM       ==> Permutation
+    PERMGRP   ==> PermutationGroup
+
+    public ==> with
+
+      symmetricGroup:       PI        -> PERMGRP I
+        ++ symmetricGroup(n) constructs the symmetric group {\em Sn}
+        ++ acting on the integers 1,...,n, generators are the
+        ++ {\em n}-cycle {\em (1,...,n)} and the 2-cycle {\em (1,2)}.
+      symmetricGroup:       L I       -> PERMGRP I
+        ++ symmetricGroup(li) constructs the symmetric group acting on
+        ++ the integers in the list {\em li}, generators are the
+        ++ cycle given by {\em li} and the 2-cycle {\em (li.1,li.2)}.
+        ++ Note: duplicates in the list will be removed.
+      alternatingGroup:     PI        -> PERMGRP I
+        ++ alternatingGroup(n) constructs the alternating group {\em An}
+        ++ acting on the integers 1,...,n,  generators are in general the
+        ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
+        ++ if n is odd and the product of the 2-cycle {\em (1,2)} with
+        ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
+        ++ if n is even.
+      alternatingGroup:     L I       -> PERMGRP I
+        ++ alternatingGroup(li) constructs the alternating group acting
+        ++ on the integers in the list {\em li}, generators are in general the
+        ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
+        ++ {\em (li.1,li.2,li.3)}, if n is odd and
+        ++ product of the 2-cycle {\em (li.1,li.2)} with
+        ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
+        ++ {\em (li.1,li.2,li.3)}, if n is even.
+        ++ Note: duplicates in the list will be removed.
+      abelianGroup:         L PI      -> PERMGRP I
+        ++ abelianGroup([n1,...,nk]) constructs the abelian group that
+        ++ is the direct product of cyclic groups with order {\em ni}.
+      cyclicGroup:          PI        -> PERMGRP I
+        ++ cyclicGroup(n) constructs the cyclic group of order n acting
+        ++ on the integers 1,...,n.
+      cyclicGroup:          L I       -> PERMGRP I
+        ++ cyclicGroup([i1,...,ik]) constructs the cyclic group of
+        ++ order k acting on the integers {\em i1},...,{\em ik}.
+        ++ Note: duplicates in the list will be removed.
+      dihedralGroup:        PI        -> PERMGRP I
+        ++ dihedralGroup(n) constructs the dihedral group of order 2n
+        ++ acting on integers 1,...,N.
+      dihedralGroup:        L I       -> PERMGRP I
+        ++ dihedralGroup([i1,...,ik]) constructs the dihedral group of
+        ++ order 2k acting on the integers out of {\em i1},...,{\em ik}.
+        ++ Note: duplicates in the list will be removed.
+      mathieu11:            L I       -> PERMGRP I
+        ++ mathieu11(li) constructs the mathieu group acting on the 11
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed.
+        ++ error, if {\em li} has less or more than 11 different entries.
+      mathieu11:            ()        -> PERMGRP I
+        ++ mathieu11 constructs the mathieu group acting on the
+        ++ integers 1,...,11.
+      mathieu12:            L I       -> PERMGRP I
+        ++ mathieu12(li) constructs the mathieu group acting on the 12
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed
+        ++ Error: if {\em li} has less or more than 12 different entries.
+      mathieu12:            ()        -> PERMGRP I
+        ++ mathieu12 constructs the mathieu group acting on the
+        ++ integers 1,...,12.
+      mathieu22:            L I       -> PERMGRP I
+        ++ mathieu22(li) constructs the mathieu group acting on the 22
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed.
+        ++ Error: if {\em li} has less or more than 22 different entries.
+      mathieu22:            ()        -> PERMGRP I
+        ++ mathieu22 constructs the mathieu group acting on the
+        ++ integers 1,...,22.
+      mathieu23:            L I       -> PERMGRP I
+        ++ mathieu23(li) constructs the mathieu group acting on the 23
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed.
+        ++ Error: if {\em li} has less or more than 23 different entries.
+      mathieu23:            ()        -> PERMGRP I
+        ++ mathieu23 constructs the mathieu group acting on the
+        ++ integers 1,...,23.
+      mathieu24:            L I       -> PERMGRP I
+        ++ mathieu24(li) constructs the mathieu group acting on the 24
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed.
+        ++ Error: if {\em li} has less or more than 24 different entries.
+      mathieu24:            ()        -> PERMGRP I
+        ++ mathieu24 constructs the mathieu group acting on the
+        ++ integers 1,...,24.
+      janko2:               L I       -> PERMGRP I
+        ++ janko2(li) constructs the janko group acting on the 100
+        ++ integers given in the list {\em li}.
+        ++ Note: duplicates in the list will be removed.
+        ++ Error: if {\em li} has less or more than 100 different entries
+      janko2:               ()        -> PERMGRP I
+        ++ janko2 constructs the janko group acting on the
+        ++ integers 1,...,100.
+      rubiksGroup:          ()        -> PERMGRP I
+        ++ rubiksGroup constructs the permutation group representing
+        ++ Rubic's Cube acting on integers {\em 10*i+j} for
+        ++ {\em 1 <= i <= 6}, {\em 1 <= j <= 8}.
+        ++ The faces of Rubik's Cube are labelled in the obvious way
+        ++ Front, Right, Up, Down, Left, Back and numbered from 1 to 6
+        ++ in this given ordering, the pieces on each face
+        ++ (except the unmoveable center piece) are clockwise numbered
+        ++ from 1 to 8 starting with the piece in the upper left
+        ++ corner. The moves of the cube are represented as permutations
+        ++ on these pieces, represented as a two digit
+        ++ integer {\em ij} where i is the numer of theface (1 to 6)
+        ++ and j is the number of the piece on this face.
+        ++ The remaining ambiguities are resolved by looking
+        ++ at the 6 generators, which represent a 90 degree turns of the
+        ++ faces, or from the following pictorial description.
+        ++ Permutation group representing Rubic's Cube acting on integers
+        ++ 10*i+j for 1 <= i <= 6, 1 <= j <=8.
+        ++
+        ++ \begin{verbatim}
+        ++ Rubik's Cube:   +-----+ +-- B   where: marks Side # :
+        ++                / U   /|/
+        ++               /     / |         F(ront)    <->    1
+        ++       L -->  +-----+ R|         R(ight)    <->    2
+        ++              |     |  +         U(p)       <->    3
+        ++              |  F  | /          D(own)     <->    4
+        ++              |     |/           L(eft)     <->    5
+        ++              +-----+            B(ack)     <->    6
+        ++                 ^
+        ++                 |
+        ++                 D
+        ++
+        ++ The Cube's surface:
+        ++                                The pieces on each side
+        ++             +---+              (except the unmoveable center
+        ++             |567|              piece) are clockwise numbered
+        ++             |4U8|              from 1 to 8 starting with the
+        ++             |321|              piece in the upper left
+        ++         +---+---+---+          corner (see figure on the
+        ++         |781|123|345|          left).  The moves of the cube
+        ++         |6L2|8F4|2R6|          are represented as
+        ++         |543|765|187|          permutations on these pieces.
+        ++         +---+---+---+          Each of the pieces is
+        ++             |123|              represented as a two digit
+        ++             |8D4|              integer ij where i is the
+        ++             |765|              # of the side ( 1 to 6 for
+        ++             +---+              F to B (see table above ))
+        ++             |567|              and j is the # of the piece.
+        ++             |4B8|
+        ++             |321|
+        ++             +---+
+        ++ \end{verbatim}
+      youngGroup:           L I      -> PERMGRP I
+        ++ youngGroup([n1,...,nk]) constructs the direct product of the
+        ++ symmetric groups {\em Sn1},...,{\em Snk}.
+      youngGroup:    Partition        -> PERMGRP I
+        ++ youngGroup(lambda) constructs the direct product of the symmetric
+        ++ groups given by the parts of the partition {\em lambda}.
+
+    private ==> add
+
+      -- import the permutation and permutation group domains:
+
+      import PERM I
+      import PERMGRP I
+
+      -- import the needed map function:
+
+      import ListFunctions2(L L I,PERM I)
+      -- the internal functions:
+
+      llli2gp(l:L L L I):PERMGRP I ==
+        --++ Converts an list of permutations each represented by a list
+        --++ of cycles ( each of them represented as a list of Integers )
+        --++ to the permutation group generated by these permutations.
+        (map(cycles,l))::PERMGRP I
+
+      li1n(n:I):L I ==
+        --++ constructs the list of integers from 1 to n
+        [i for i in 1..n]
+
+      -- definition of the exported functions:
+      youngGroup(l:L I):PERMGRP I ==
+        gens:= nil()$(L L L I)
+        element:I:= 1
+        for n in l | n > 1 repeat
+          gens:=cons(list [i for i in element..(element+n-1)], gens)
+          if n >= 3 then gens := cons([[element,element+1]],gens)
+          element:=element+n
+        llli2gp
+          #gens = 0 => [[[1]]]
+          gens
+
+      youngGroup(lambda : Partition):PERMGRP I ==
+        youngGroup(convert(lambda)$Partition)
+
+      rubiksGroup():PERMGRP I ==
+        -- each generator represents a 90 degree turn of the appropriate
+        -- side.
+        f:L L I:=
+         [[11,13,15,17],[12,14,16,18],[51,31,21,41],[53,33,23,43],[52,32,22,42]]
+        r:L L I:=
+         [[21,23,25,27],[22,24,26,28],[13,37,67,43],[15,31,61,45],[14,38,68,44]]
+        u:L L I:=
+         [[31,33,35,37],[32,34,36,38],[13,51,63,25],[11,57,61,23],[12,58,62,24]]
+        d:L L I:=
+         [[41,43,45,47],[42,44,46,48],[17,21,67,55],[15,27,65,53],[16,28,66,54]]
+        l:L L I:=
+         [[51,53,55,57],[52,54,56,58],[11,41,65,35],[17,47,63,33],[18,48,64,34]]
+        b:L L I:=
+         [[61,63,65,67],[62,64,66,68],[45,25,35,55],[47,27,37,57],[46,26,36,56]]
+        llli2gp [f,r,u,d,l,b]
+
+      mathieu11(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 11 => error "Exactly 11 integers for mathieu11 needed !"
+        a:L L I:=[[l.1,l.10],[l.2,l.8],[l.3,l.11],[l.5,l.7]]
+        llli2gp [a,[[l.1,l.4,l.7,l.6],[l.2,l.11,l.10,l.9]]]
+
+      mathieu11():PERMGRP I == mathieu11 li1n 11
+
+      mathieu12(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 12 => error "Exactly 12 integers for mathieu12 needed !"
+        a:L L I:=
+          [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11]]
+        llli2gp [a,[[l.1,l.6,l.5,l.8,l.3,l.7,l.4,l.2,l.9,l.10],[l.11,l.12]]]
+
+      mathieu12():PERMGRP I == mathieu12 li1n 12
+
+      mathieu22(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 22 => error "Exactly 22 integers for mathieu22 needed !"
+        a:L L I:=[[l.1,l.2,l.4,l.8,l.16,l.9,l.18,l.13,l.3,l.6,l.12],   _
+          [l.5,l.10,l.20,l.17,l.11,l.22,l.21,l.19,l.15,l.7,l.14]]
+        b:L L I:= [[l.1,l.2,l.6,l.18],[l.3,l.15],[l.5,l.8,l.21,l.13],   _
+          [l.7,l.9,l.20,l.12],[l.10,l.16],[l.11,l.19,l.14,l.22]]
+        llli2gp [a,b]
+
+      mathieu22():PERMGRP I == mathieu22 li1n 22
+
+      mathieu23(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 23 => error "Exactly 23 integers for mathieu23 needed !"
+        a:L L I:= [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11,l.12,l.13,l.14,_
+                   l.15,l.16,l.17,l.18,l.19,l.20,l.21,l.22,l.23]]
+        b:L L I:= [[l.2,l.16,l.9,l.6,l.8],[l.3,l.12,l.13,l.18,l.4],              _
+                   [l.7,l.17,l.10,l.11,l.22],[l.14,l.19,l.21,l.20,l.15]]
+        llli2gp [a,b]
+
+      mathieu23():PERMGRP I == mathieu23 li1n 23
+
+      mathieu24(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 24 => error "Exactly 24 integers for mathieu24 needed !"
+        a:L L I:= [[l.1,l.16,l.10,l.22,l.24],[l.2,l.12,l.18,l.21,l.7],          _
+                   [l.4,l.5,l.8,l.6,l.17],[l.9,l.11,l.13,l.19,l.15]]
+        b:L L I:= [[l.1,l.22,l.13,l.14,l.6,l.20,l.3,l.21,l.8,l.11],[l.2,l.10],  _
+                   [l.4,l.15,l.18,l.17,l.16,l.5,l.9,l.19,l.12,l.7],[l.23,l.24]]
+        llli2gp [a,b]
+
+      mathieu24():PERMGRP I == mathieu24 li1n 24
+
+      janko2(l:L I):PERMGRP I ==
+      -- permutations derived from the ATLAS
+        l:=removeDuplicates l
+        #l ^= 100 => error "Exactly 100 integers for janko2 needed !"
+        a:L L I:=[                                                            _
+                 [l.2,l.3,l.4,l.5,l.6,l.7,l.8],                               _
+                 [l.9,l.10,l.11,l.12,l.13,l.14,l.15],                         _
+                 [l.16,l.17,l.18,l.19,l.20,l.21,l.22],                        _
+                 [l.23,l.24,l.25,l.26,l.27,l.28,l.29],                        _
+                 [l.30,l.31,l.32,l.33,l.34,l.35,l.36],                        _
+                 [l.37,l.38,l.39,l.40,l.41,l.42,l.43],                        _
+                 [l.44,l.45,l.46,l.47,l.48,l.49,l.50],                        _
+                 [l.51,l.52,l.53,l.54,l.55,l.56,l.57],                        _
+                 [l.58,l.59,l.60,l.61,l.62,l.63,l.64],                        _
+                 [l.65,l.66,l.67,l.68,l.69,l.70,l.71],                        _
+                 [l.72,l.73,l.74,l.75,l.76,l.77,l.78],                        _
+                 [l.79,l.80,l.81,l.82,l.83,l.84,l.85],                        _
+                 [l.86,l.87,l.88,l.89,l.90,l.91,l.92],                        _
+                 [l.93,l.94,l.95,l.96,l.97,l.98,l.99] ]
+        b:L L I:=[
+                [l.1,l.74,l.83,l.21,l.36,l.77,l.44,l.80,l.64,l.2,l.34,l.75,l.48,l.17,l.100],_
+                [l.3,l.15,l.31,l.52,l.19,l.11,l.73,l.79,l.26,l.56,l.41,l.99,l.39,l.84,l.90],_
+                [l.4,l.57,l.86,l.63,l.85,l.95,l.82,l.97,l.98,l.81,l.8,l.69,l.38,l.43,l.58],_
+                [l.5,l.66,l.49,l.59,l.61],_
+                [l.6,l.68,l.89,l.94,l.92,l.20,l.13,l.54,l.24,l.51,l.87,l.27,l.76,l.23,l.67],_
+                [l.7,l.72,l.22,l.35,l.30,l.70,l.47,l.62,l.45,l.46,l.40,l.28,l.65,l.93,l.42],_
+                [l.9,l.71,l.37,l.91,l.18,l.55,l.96,l.60,l.16,l.53,l.50,l.25,l.32,l.14,l.33],_
+                [l.10,l.78,l.88,l.29,l.12] ]
+        llli2gp [a,b]
+
+      janko2():PERMGRP I == janko2 li1n 100
+
+      abelianGroup(l:L PI):PERMGRP I ==
+        gens:= nil()$(L L L I)
+        element:I:= 1
+        for n in l | n > 1 repeat
+          gens:=cons( list [i for i in element..(element+n-1) ], gens )
+          element:=element+n
+        llli2gp
+          #gens = 0 => [[[1]]]
+          gens
+
+      alternatingGroup(l:L I):PERMGRP I ==
+        l:=removeDuplicates l
+        #l = 0 =>
+          error "Cannot construct alternating group on empty set"
+        #l < 3 => llli2gp [[[l.1]]]
+        #l = 3 => llli2gp [[[l.1,l.2,l.3]]]
+        tmp:= [l.i for i in 3..(#l)]
+        gens:L L L I:=[[tmp],[[l.1,l.2,l.3]]]
+        odd?(#l) => llli2gp gens
+        gens.1 := cons([l.1,l.2],gens.1)
+        llli2gp gens
+
+      alternatingGroup(n:PI):PERMGRP I == alternatingGroup li1n n
+
+      symmetricGroup(l:L I):PERMGRP I ==
+        l:=removeDuplicates l
+        #l = 0 => error "Cannot construct symmetric group on empty set !"
+        #l < 3 => llli2gp [[l]]
+        llli2gp [[l],[[l.1,l.2]]]
+
+      symmetricGroup(n:PI):PERMGRP I == symmetricGroup li1n n
+
+      cyclicGroup(l:L I):PERMGRP I ==
+        l:=removeDuplicates l
+        #l = 0 => error "Cannot construct cyclic group on empty set"
+        llli2gp [[l]]
+
+      cyclicGroup(n:PI):PERMGRP I == cyclicGroup li1n n
+
+      dihedralGroup(l:L I):PERMGRP I ==
+        l:=removeDuplicates l
+        #l < 3 => error "in dihedralGroup: Minimum of 3 elements needed !"
+        tmp := [[l.i, l.(#l-i+1) ] for i in 1..(#l quo 2)]
+        llli2gp [ [ l ], tmp ]
+
+      dihedralGroup(n:PI):PERMGRP I ==
+        n = 1 => symmetricGroup (2::PI)
+        n = 2 => llli2gp [[[1,2]],[[3,4]]]
+        dihedralGroup li1n n
+
+@
+<<PGE.dotabb>>=
+"PGE" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PGE"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PGE" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PICOERCE PiCoercions}
 \pagehead{PiCoercions}{PICOERCE}
 \pagepic{ps/v104picoercions.ps}{PICOERCE}{1.00}
@@ -57441,6 +61409,149 @@ PiCoercions(R:Join(OrderedSet, IntegralDomain)): with
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PLOT1 PlotFunctions1}
+\pagehead{PlotFunctions1}{PLOT1}
+\pagepic{ps/v104plotfunctions1.ps}{PLOT1}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PLOT1 PlotFunctions1>>=
+)abbrev package PLOT1 PlotFunctions1
+++ Authors: R.T.M. Bronstein, C.J. Williamson
+++ Date Created: Jan 1989
+++ Date Last Updated: 4 Mar 1990
+++ Basic Operations: plot, plotPolar
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: PlotFunctions1 provides facilities for plotting curves
+++ where functions SF -> SF are specified by giving an expression
+PlotFunctions1(S:ConvertibleTo InputForm): with
+    plot : (S, Symbol, Segment DoubleFloat) -> Plot
+      ++ plot(fcn,x,seg) plots the graph of \spad{y = f(x)} on a interval
+    plot : (S, S, Symbol, Segment DoubleFloat) -> Plot
+      ++ plot(f,g,t,seg) plots the graph of \spad{x = f(t)}, \spad{y = g(t)} as t
+      ++ ranges over an interval.
+    plotPolar : (S, Symbol, Segment DoubleFloat) -> Plot
+      ++ plotPolar(f,theta,seg) plots the graph of \spad{r = f(theta)} as
+      ++ theta ranges over an interval
+    plotPolar : (S, Symbol) -> Plot
+      ++ plotPolar(f,theta) plots the graph of \spad{r = f(theta)} as
+      ++ theta ranges from 0 to 2 pi
+  == add
+    import MakeFloatCompiledFunction(S)
+
+    plot(f, x, xRange) == plot(makeFloatFunction(f, x), xRange)
+    plotPolar(f,theta) == plotPolar(makeFloatFunction(f,theta))
+    plot(f1, f2, t, tRange) ==
+      plot(makeFloatFunction(f1, t), makeFloatFunction(f2, t), tRange)
+    plotPolar(f,theta,thetaRange) ==
+      plotPolar(makeFloatFunction(f,theta),thetaRange)
+
+@
+<<PLOT1.dotabb>>=
+"PLOT1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PLOT1"]
+"KONVERT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=KONVERT"]
+"PLOT1" -> "KONVERT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PLOTTOOL PlotTools}
+\pagehead{PlotTools}{PLOTTOOL}
+\pagepic{ps/v104plottools.ps}{PLOTTOOL}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PLOTTOOL PlotTools>>=
+)abbrev package PLOTTOOL PlotTools
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package exports plotting tools 
+PlotTools(): Exports == Implementation where
+  L   ==> List
+--  Pt  ==> TwoDimensionalPoint
+  SEG ==> Segment
+  SF  ==> DoubleFloat
+  Pt ==> Point(SF)
+  PLOT ==> Plot 
+  DROP ==> DrawOption
+  S    ==> String
+  VIEW2D ==> TwoDimensionalViewport
+
+  Exports ==> with
+    calcRanges: L L Pt             -> L SEG SF
+	++ calcRanges(l) \undocumented
+ 
+  Implementation ==> add
+    import GraphicsDefaults
+    import PLOT
+    import TwoDimensionalPlotClipping
+    import DrawOptionFunctions0
+    import ViewportPackage
+    import POINT
+    import PointPackage(SF)
+ 
+    --%Local functions
+    xRange0: L Pt -> SEG SF
+    xRange: L L Pt -> SEG SF
+    yRange0: L Pt -> SEG SF
+    yRange: L L Pt -> SEG SF
+    drawToScaleRanges: (SEG SF,SEG SF) -> L SEG SF
+  
+    drawToScaleRanges(xVals,yVals) ==
+      xDiff := (xHi := hi xVals) - (xLo := lo xVals)
+      yDiff := (yHi := hi yVals) - (yLo := lo yVals)
+      pad := abs(yDiff - xDiff)/2
+      yDiff > xDiff => [segment(xLo - pad,xHi + pad),yVals]
+      [xVals,segment(yLo - pad,yHi + pad)]
+ 
+    select : (L Pt,Pt -> SF,(SF,SF) -> SF) -> SF
+    select(l,f,g) ==
+      m := f first l
+      for p in rest l repeat m := g(m,f p)
+      m
+ 
+    xRange0(list:L Pt) == select(list,xCoord,min) .. select(list,xCoord,max)
+    yRange0(list:L Pt) == select(list,yCoord,min) .. select(list,yCoord,max)
+ 
+    select2: (L L Pt,L Pt -> SF,(SF,SF) -> SF) -> SF
+    select2(l,f,g) ==
+      m := f first l
+      for p in rest l repeat m := g(m,f p)
+      m
+ 
+    xRange(list:L L Pt) ==
+      select2(list,lo(xRange0(#1)),min) .. select2(list,hi(xRange0(#1)),max)
+ 
+    yRange(list:L L Pt) ==
+      select2(list,lo(yRange0(#1)),min) .. select2(list,hi(yRange0(#1)),max)
+
+  --%Exported Functions
+    calcRanges(llp) ==
+      drawToScale() => drawToScaleRanges(xRange llp, yRange llp)
+      [xRange llp, yRange llp]
+
+@
+<<PLOTTOOL.dotabb>>=
+"PLOTTOOL" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PLOTTOOL"]
+"FIELD"  [color="#4488FF",href="bookvol10.2.pdf#nameddest=FIELD"]
+"RADCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=RADCAT"]
+"PLOTTOOL" -> "FIELD"
+"PLOTTOOL" -> "RADCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PTFUNC2 PointFunctions2}
 \pagehead{PointFunctions2}{PTFUNC2}
 \pagepic{ps/v104pointfunctions2.ps}{PTFUNC2}{1.00}
@@ -57577,6 +61688,630 @@ PointPackage(R:Ring):Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFO PointsOfFiniteOrder}
+\pagehead{PointsOfFiniteOrder}{PFO}
+\pagepic{ps/v104pointsoffiniteorder.ps}{PFO}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFO PointsOfFiniteOrder>>=
+)abbrev package PFO PointsOfFiniteOrder
+++ Finds the order of a divisor on a curve
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 22 July 1998
+++ Description:
+++ This package provides function for testing whether a divisor on a
+++ curve is a torsion divisor.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r PFO INPUT
+PointsOfFiniteOrder(R0, F, UP, UPUP, R): Exports == Implementation where
+  R0   : Join(OrderedSet, IntegralDomain, RetractableTo Integer)
+  F    : FunctionSpace R0
+  UP   : UnivariatePolynomialCategory F
+  UPUP : UnivariatePolynomialCategory Fraction UP
+  R    : FunctionFieldCategory(F, UP, UPUP)
+
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  Q   ==> Fraction Integer
+  UPF ==> SparseUnivariatePolynomial F
+  UPQ ==> SparseUnivariatePolynomial Q
+  QF  ==> Fraction UP
+  UPUPQ ==> SparseUnivariatePolynomial Fraction UPQ
+  UP2 ==> SparseUnivariatePolynomial UPQ
+  UP3 ==> SparseUnivariatePolynomial UP2
+  FD  ==> FiniteDivisor(F, UP, UPUP, R)
+  K   ==> Kernel F
+  REC ==> Record(ncurve:UP3, disc:Z, dfpoly:UPQ)
+  RC0 ==> Record(ncurve:UPUPQ, disc:Z)
+  ID  ==> FractionalIdeal(UP, QF, UPUP, R)
+  SMP ==> SparseMultivariatePolynomial(R0,K)
+  ALGOP  ==> "%alg"
+
+  Exports ==> with
+    order        : FD -> Union(N, "failed")
+	++ order(f) \undocumented
+    torsion?     : FD -> Boolean
+	++ torsion?(f) \undocumented
+    torsionIfCan : FD -> Union(Record(order:N, function:R), "failed")
+	++ torsionIfCan(f)\ undocumented
+
+  Implementation ==> add
+    import IntegerPrimesPackage(Z)
+    import PointsOfFiniteOrderTools(UPQ, UPUPQ)
+    import UnivariatePolynomialCommonDenominator(Z, Q, UPQ)
+
+    cmult: List SMP -> SMP
+    raise         : (UPQ, K) -> F
+    raise2        : (UP2, K) -> UP
+    qmod          : F     -> Q
+    fmod          : UPF   -> UPQ
+    rmod          : UP    -> UPQ
+    pmod          : UPUP  -> UPUPQ
+    kqmod         : (F,    K) -> UPQ
+    krmod         : (UP,   K) -> UP2
+    kpmod         : (UPUP, K) -> UP3
+    selectIntegers: K   -> REC
+    selIntegers:    ()  -> RC0
+    possibleOrder : FD -> N
+    ratcurve      : (FD, RC0)    -> N
+    algcurve      : (FD, REC, K) -> N
+    kbad3Num      : (UP3, UPQ) -> Z
+    kbadBadNum    : (UP2, UPQ) -> Z
+    kgetGoodPrime : (REC, UPQ, UP3, UP2,UP2) -> Record(prime:PI,poly:UPQ)
+    goodRed       : (REC, UPQ, UP3, UP2, UP2, PI) -> Union(UPQ, "failed")
+    good?         : (UPQ, UP3, UP2, UP2, PI, UPQ) -> Boolean
+    klist         : UP -> List K
+    aklist        : R  -> List K
+    alglist       : FD -> List K
+    notIrr?       : UPQ -> Boolean
+    rat           : (UPUP, FD, PI) -> N
+    toQ1          : (UP2, UPQ) -> UP
+    toQ2          : (UP3, UPQ) -> R
+    Q2F           : Q -> F
+    Q2UPUP        : UPUPQ -> UPUP
+
+    q := FunctionSpaceReduce(R0, F)
+
+    torsion? d == order(d) case N
+    Q2F x      == numer(x)::F / denom(x)::F
+    qmod x     == bringDown(x)$q
+    kqmod(x,k) == bringDown(x, k)$q
+    fmod p     == map(qmod, p)$SparseUnivariatePolynomialFunctions2(F, Q)
+    pmod p     == map(qmod, p)$MultipleMap(F, UP, UPUP, Q, UPQ, UPUPQ)
+    Q2UPUP p   == map(Q2F, p)$MultipleMap(Q, UPQ, UPUPQ, F, UP, UPUP)
+    klist d    == "setUnion"/[kernels c for c in coefficients d]
+    notIrr? d  == #(factors factor(d)$RationalFactorize(UPQ)) > 1
+    kbadBadNum(d, m) == mix [badNum(c rem m) for c in coefficients d]
+    kbad3Num(h, m)   == lcm [kbadBadNum(c, m) for c in coefficients h]
+    
+    torsionIfCan d ==
+      zero?(n := possibleOrder(d := reduce d)) => "failed"
+      (g := generator reduce(n::Z * d)) case "failed" => "failed"
+      [n, g::R]
+
+    UPQ2F(p:UPQ, k:K):F ==
+      map(Q2F, p)$UnivariatePolynomialCategoryFunctions2(Q, UPQ, F, UP) (k::F)
+
+    UP22UP(p:UP2, k:K):UP ==
+      map(UPQ2F(#1, k), p)$UnivariatePolynomialCategoryFunctions2(UPQ,UP2,F,UP)
+
+    UP32UPUP(p:UP3, k:K):UPUP ==
+      map(UP22UP(#1,k)::QF,
+          p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
+
+    if R0 has GcdDomain then
+       cmult(l:List SMP):SMP == lcm l
+    else
+       cmult(l:List SMP):SMP == */l
+
+    doubleDisc(f:UP3):Z ==
+      d := discriminant f
+      g := gcd(d, differentiate d)
+      d := (d exquo g)::UP2
+      zero?(e := discriminant d) => 0
+      gcd [retract(c)@Z for c in coefficients e]
+
+    commonDen(p:UP):SMP ==
+      l1:List F := coefficients p
+      l2:List SMP := [denom c for c in l1]
+      cmult l2
+
+    polyred(f:UPUP):UPUP ==
+      cmult([commonDen(retract(c)@UP) for c in coefficients f])::F::UP::QF * f
+
+    aklist f ==
+      (r := retractIfCan(f)@Union(QF, "failed")) case "failed" =>
+        "setUnion"/[klist(retract(c)@UP) for c in coefficients lift f]
+      klist(retract(r::QF)@UP)
+
+    alglist d ==
+      n := numer(i := ideal d)
+      select_!(has?(operator #1, ALGOP),
+               setUnion(klist denom i,
+                 "setUnion"/[aklist qelt(n,i) for i in minIndex n..maxIndex n]))
+
+    krmod(p,k) ==
+       map(kqmod(#1, k),
+           p)$UnivariatePolynomialCategoryFunctions2(F, UP, UPQ, UP2)
+
+    rmod p ==
+       map(qmod, p)$UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
+
+    raise(p, k) ==
+      (map(Q2F, p)$SparseUnivariatePolynomialFunctions2(Q, F)) (k::F)
+
+    raise2(p, k) ==
+      map(raise(#1, k),
+          p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
+
+    algcurve(d, rc, k) ==
+      mn := minIndex(n := numer(i := minimize ideal d))
+      h  := kpmod(lift(hh := n(mn + 1)), k)
+      b2 := primitivePart
+                 raise2(b := krmod(retract(retract(n.mn)@QF)@UP, k), k)
+      s  := kqmod(resultant(primitivePart separate(raise2(krmod(
+                    retract(norm hh)@UP, k), k), b2).primePart, b2), k)
+      pr := kgetGoodPrime(rc, s, h, b, dd := krmod(denom i, k))
+      p  := pr.prime
+      pp := UP32UPUP(rc.ncurve, k)
+      mm := pr.poly
+      gf := InnerPrimeField p
+      m  := map(retract(#1)@Z :: gf,
+                         mm)$SparseUnivariatePolynomialFunctions2(Q, gf)
+--      one? degree m =>
+      (degree m = 1) =>
+        alpha := - coefficient(m, 0) / leadingCoefficient m
+        order(d, pp,
+           (map(numer(#1)::gf / denom(#1)::gf,
+            kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))(alpha)
+                                   )$ReducedDivisor(F, UP, UPUP, R, gf)
+        -- d1 := toQ1(dd, mm)
+        -- rat(pp, divisor ideal([(toQ1(b, mm) / d1)::QF::R,
+                                       -- inv(d1::QF) * toQ2(h,mm)])$ID, p)
+      sae:= SimpleAlgebraicExtension(gf,SparseUnivariatePolynomial gf,m)
+      order(d, pp,
+           reduce(map(numer(#1)::gf / denom(#1)::gf,
+            kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))$sae
+                                   )$ReducedDivisor(F, UP, UPUP, R, sae)
+
+-- returns the potential order of d, 0 if d is of infinite order
+    ratcurve(d, rc) ==
+      mn  := minIndex(nm := numer(i := minimize ideal d))
+      h   := pmod lift(hh := nm(mn + 1))
+      b   := rmod(retract(retract(nm.mn)@QF)@UP)
+      s   := separate(rmod(retract(norm hh)@UP), b).primePart
+      bd  := badNum rmod denom i
+      r   := resultant(s, b)
+      bad := lcm [rc.disc, numer r, denom r, bd.den*bd.gcdnum, badNum h]$List(Z)
+      pp  := Q2UPUP(rc.ncurve)
+      n   := rat(pp, d, p := getGoodPrime bad)
+-- if n > 1 then it is cheaper to compute the order modulo a second prime,
+-- since computing n * d could be very expensive
+--      one? n => n
+      (n = 1) => n
+      m   := rat(pp, d, getGoodPrime(p * bad))
+      n = m => n
+      0
+
+-- returns the order of d mod p
+    rat(pp, d, p) ==
+      gf := InnerPrimeField p
+      order(d, pp, (qq := qmod #1;numer(qq)::gf / denom(qq)::gf)
+                                    )$ReducedDivisor(F, UP, UPUP, R, gf)
+
+-- returns the potential order of d, 0 if d is of infinite order
+    possibleOrder d ==
+--      zero?(genus()) or one?(#(numer ideal d)) => 1
+      zero?(genus()) or (#(numer ideal d) = 1) => 1
+      empty?(la := alglist d) => ratcurve(d, selIntegers())
+      not(empty? rest la) =>
+           error "PFO::possibleOrder: more than 1 algebraic constant"
+      algcurve(d, selectIntegers first la, first la)
+
+    selIntegers():RC0 ==
+      f := definingPolynomial()$R
+      while zero?(d := doubleDisc(r := polyred pmod f)) repeat newReduc()$q
+      [r, d]
+
+    selectIntegers(k:K):REC ==
+      g := polyred(f := definingPolynomial()$R)
+      p := minPoly k
+      while zero?(d := doubleDisc(r := kpmod(g, k))) or (notIrr? fmod p)
+          repeat newReduc()$q
+      [r, d, splitDenominator(fmod p).num]
+
+    toQ1(p, d) ==
+      map(Q2F(retract(#1 rem d)@Q),
+          p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
+
+    toQ2(p, d) ==
+      reduce map(toQ1(#1, d)::QF,
+        p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
+
+    kpmod(p, k) ==
+      map(krmod(retract(#1)@UP, k),
+        p)$UnivariatePolynomialCategoryFunctions2(QF, UPUP, UP2, UP3)
+
+    order d ==
+      zero?(n := possibleOrder(d := reduce d)) => "failed"
+      principal? reduce(n::Z * d) => n
+      "failed"
+
+    kgetGoodPrime(rec, res, h, b, d) ==
+      p:PI := 3
+      while (u := goodRed(rec, res, h, b, d, p)) case "failed" repeat
+        p := nextPrime(p::Z)::PI
+      [p, u::UPQ]
+
+    goodRed(rec, res, h, b, d, p) ==
+      zero?(rec.disc rem p) => "failed"
+      gf := InnerPrimeField p
+      l  := [f.factor for f in factors factor(map(retract(#1)@Z :: gf,
+               rec.dfpoly)$SparseUnivariatePolynomialFunctions2(Q,
+                 gf))$DistinctDegreeFactorize(gf,
+--                   SparseUnivariatePolynomial gf) | one?(f.exponent)]
+                   SparseUnivariatePolynomial gf) | (f.exponent = 1)]
+      empty? l => "failed"
+      mdg := first l
+      for ff in rest l repeat
+        if degree(ff) < degree(mdg) then mdg := ff
+      md := map(convert(#1)@Z :: Q,
+                 mdg)$SparseUnivariatePolynomialFunctions2(gf, Q)
+      good?(res, h, b, d, p, md) => md
+      "failed"
+
+    good?(res, h, b, d, p, m) ==
+      bd := badNum(res rem m)
+      not (zero?(bd.den rem p) or zero?(bd.gcdnum rem p) or
+        zero?(kbadBadNum(b,m) rem p) or zero?(kbadBadNum(d,m) rem p)
+              or zero?(kbad3Num(h, m) rem p))
+
+@
+<<PFO.dotabb>>=
+"PFO" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFO"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"FFCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FFCAT"]
+"PFO" -> "FS"
+"PFO" -> "FFCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFOQ PointsOfFiniteOrderRational}
+\pagehead{PointsOfFiniteOrderRational}{PFOQ}
+\pagepic{ps/v104pointsoffiniteorderrational.ps}{PFOQ}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFOQ PointsOfFiniteOrderRational>>=
+)abbrev package PFOQ PointsOfFiniteOrderRational
+++ Finds the order of a divisor on a rational curve
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1988
+++ Date Last Updated: 3 August 1993
+++ Description:
+++ This package provides function for testing whether a divisor on a
+++ curve is a torsion divisor.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r PFOQ INPUT
+PointsOfFiniteOrderRational(UP, UPUP, R): Exports == Implementation where
+  UP   : UnivariatePolynomialCategory Fraction Integer
+  UPUP : UnivariatePolynomialCategory Fraction UP
+  R    : FunctionFieldCategory(Fraction Integer, UP, UPUP)
+
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  Q   ==> Fraction Integer
+  FD  ==> FiniteDivisor(Q, UP, UPUP, R)
+
+  Exports ==> with
+    order       : FD -> Union(N, "failed")
+	++ order(f) \undocumented
+    torsion?    : FD -> Boolean
+	++ torsion?(f) \undocumented
+    torsionIfCan: FD -> Union(Record(order:N, function:R), "failed")
+	++ torsionIfCan(f) \undocumented
+
+  Implementation ==> add
+    import PointsOfFiniteOrderTools(UP, UPUP)
+
+    possibleOrder: FD -> N
+    ratcurve     : (FD, UPUP, Z) -> N
+    rat          : (UPUP, FD, PI) -> N
+
+    torsion? d  == order(d) case N
+
+-- returns the potential order of d, 0 if d is of infinite order
+    ratcurve(d, modulus, disc) ==
+      mn  := minIndex(nm := numer(i := ideal d))
+      h   := lift(hh := nm(mn + 1))
+      s   := separate(retract(norm hh)@UP,
+               b := retract(retract(nm.mn)@Fraction(UP))@UP).primePart
+      bd  := badNum denom i
+      r   := resultant(s, b)
+      bad := lcm [disc, numer r, denom r, bd.den * bd.gcdnum, badNum h]$List(Z)
+      n   := rat(modulus, d, p := getGoodPrime bad)
+-- if n > 1 then it is cheaper to compute the order modulo a second prime,
+-- since computing n * d could be very expensive
+--      one? n => n
+      (n = 1) => n
+      m   := rat(modulus, d, getGoodPrime(p * bad))
+      n = m => n
+      0
+
+    rat(pp, d, p) ==
+      gf := InnerPrimeField p
+      order(d, pp,
+        numer(#1)::gf / denom(#1)::gf)$ReducedDivisor(Q, UP, UPUP, R, gf)
+
+-- returns the potential order of d, 0 if d is of infinite order
+    possibleOrder d ==
+--      zero?(genus()) or one?(#(numer ideal d)) => 1
+      zero?(genus()) or (#(numer ideal d) = 1) => 1
+      r := polyred definingPolynomial()$R
+      ratcurve(d, r, doubleDisc r)
+
+    order d ==
+      zero?(n := possibleOrder(d := reduce d)) => "failed"
+      principal? reduce(n::Z * d) => n
+      "failed"
+
+    torsionIfCan d ==
+      zero?(n := possibleOrder(d := reduce d)) => "failed"
+      (g := generator reduce(n::Z * d)) case "failed" => "failed"
+      [n, g::R]
+
+@
+<<PFOQ.dotabb>>=
+"PFOQ" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFOQ"]
+"FFCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FFCAT"]
+"PFOQ" -> "FFCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFOTOOLS PointsOfFiniteOrderTools}
+\pagehead{PointsOfFiniteOrderTools}{PFOTOOLS}
+\pagepic{ps/v104pointsoffiniteordertools.ps}{PFOTOOLS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFOTOOLS PointsOfFiniteOrderTools>>=
+)abbrev package PFOTOOLS PointsOfFiniteOrderTools
+++ Utilities for PFOQ and PFO
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1988
+++ Date Last Updated: 11 Jul 1990
+PointsOfFiniteOrderTools(UP, UPUP): Exports == Implementation where
+  UP   : UnivariatePolynomialCategory Fraction Integer
+  UPUP : UnivariatePolynomialCategory Fraction UP
+
+  PI  ==> PositiveInteger
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  Q   ==> Fraction Integer
+
+  Exports ==> with
+    getGoodPrime : Z -> PI
+      ++ getGoodPrime n returns the smallest prime not dividing n
+    badNum       : UP   -> Record(den:Z, gcdnum:Z)
+	++ badNum(p) \undocumented
+    badNum       : UPUP -> Z
+	++ badNum(u) \undocumented
+    mix          : List Record(den:Z, gcdnum:Z) -> Z
+	++ mix(l) \undocumented
+    doubleDisc   : UPUP -> Z
+	++ doubleDisc(u) \undocumented
+    polyred      : UPUP -> UPUP
+	++ polyred(u) \undocumented
+
+  Implementation ==> add
+    import IntegerPrimesPackage(Z)
+    import UnivariatePolynomialCommonDenominator(Z, Q, UP)
+
+    mix l          == lcm(lcm [p.den for p in l], gcd [p.gcdnum for p in l])
+    badNum(p:UPUP) == mix [badNum(retract(c)@UP) for c in coefficients p]
+
+    polyred r ==
+      lcm [commonDenominator(retract(c)@UP) for c in coefficients r] * r
+
+    badNum(p:UP) ==
+      cd := splitDenominator p
+      [cd.den, gcd [retract(c)@Z for c in coefficients(cd.num)]]
+
+    getGoodPrime n ==
+      p:PI := 3
+      while zero?(n rem p) repeat
+        p := nextPrime(p::Z)::PI
+      p
+
+    doubleDisc r ==
+      d := retract(discriminant r)@UP
+      retract(discriminant((d exquo gcd(d, differentiate d))::UP))@Z
+
+@
+<<PFOTOOLS.dotabb>>=
+"PFOTOOLS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFOTOOLS"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PFOTOOLS" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package POLTOPOL PolToPol}
+\pagehead{PolToPol}{POLTOPOL}
+\pagepic{ps/v104poltopol.ps}{POLTOPOL}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package POLTOPOL PolToPol>>=
+)abbrev package POLTOPOL PolToPol
+++ Author : P.Gianni, Summer '88
+++ Description:
+++ Package with the conversion functions among different kind of polynomials
+PolToPol(lv,R) : C == T
+ 
+ where
+  R      :    Ring
+  lv     :    List Symbol
+  NNI    ==>  NonNegativeInteger
+  Ov     ==>  OrderedVariableList(lv)
+  IES    ==>  IndexedExponents Symbol
+ 
+  DP     ==>  DirectProduct(#lv,NonNegativeInteger)
+  DPoly  ==>  DistributedMultivariatePolynomial(lv,R)
+ 
+  HDP    ==>  HomogeneousDirectProduct(#lv,NonNegativeInteger)
+  HDPoly ==>  HomogeneousDistributedMultivariatePolynomial(lv,R)
+  P      ==>  Polynomial R
+  VV     ==>  Vector NNI
+  MPC3   ==>  MPolyCatFunctions3
+ 
+  C == with
+     dmpToHdmp    :    DPoly    -> HDPoly
+       ++ dmpToHdmp(p) converts p from a \spadtype{DMP} to a \spadtype{HDMP}.
+     hdmpToDmp    :   HDPoly    -> DPoly
+       ++ hdmpToDmp(p) converts p from a \spadtype{HDMP} to a \spadtype{DMP}.
+     pToHdmp      :     P       -> HDPoly
+       ++ pToHdmp(p) converts p from a \spadtype{POLY} to a \spadtype{HDMP}.
+     hdmpToP      :   HDPoly    -> P
+       ++ hdmpToP(p) converts p from a \spadtype{HDMP} to a \spadtype{POLY}.
+     dmpToP       :    DPoly    -> P
+       ++ dmpToP(p) converts p from a \spadtype{DMP} to a \spadtype{POLY}.
+     pToDmp       :     P       -> DPoly
+       ++ pToDmp(p) converts p from a \spadtype{POLY} to a \spadtype{DMP}.
+  T == add
+ 
+    variable1(xx:Symbol):Ov == variable(xx)::Ov
+ 
+   -- transform a P in a HDPoly --
+    pToHdmp(pol:P) : HDPoly ==
+      map(variable1,pol)$MPC3(Symbol,Ov,IES,HDP,R,P,HDPoly)
+ 
+   -- transform an HDPoly in a P --
+    hdmpToP(hdpol:HDPoly) : P ==
+      map(convert,hdpol)$MPC3(Ov,Symbol,HDP,IES,R,HDPoly,P)
+ 
+   -- transform an DPoly in a P --
+    dmpToP(dpol:DPoly) : P ==
+      map(convert,dpol)$MPC3(Ov,Symbol,DP,IES,R,DPoly,P)
+ 
+   -- transform a P in a DPoly --
+    pToDmp(pol:P) : DPoly ==
+      map(variable1,pol)$MPC3(Symbol,Ov,IES,DP,R,P,DPoly)
+ 
+   -- transform a DPoly in a HDPoly --
+    dmpToHdmp(dpol:DPoly) : HDPoly ==
+      dpol=0 => 0$HDPoly
+      monomial(leadingCoefficient dpol,
+               directProduct(degree(dpol)::VV)$HDP)$HDPoly+
+                                                 dmpToHdmp(reductum dpol)
+ 
+   -- transform a HDPoly in a DPoly --
+    hdmpToDmp(hdpol:HDPoly) : DPoly ==
+      hdpol=0 => 0$DPoly
+      dd:DP:= directProduct((degree hdpol)::VV)$DP
+      monomial(leadingCoefficient hdpol,dd)$DPoly+
+               hdmpToDmp(reductum hdpol)
+
+@
+<<POLTOPOL.dotabb>>=
+"POLTOPOL" [color="#FF4488",href="bookvol10.4.pdf#nameddest=POLTOPOL"]
+"DIRPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=DIRPCAT"]
+"POLTOPOL" -> "DIRPCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PGROEB PolyGroebner}
+\pagehead{PolyGroebner}{PGROEB}
+\pagepic{ps/v104polygroebner.ps}{PGROEB}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PGROEB PolyGroebner>>=
+)abbrev package PGROEB PolyGroebner
+++ Author: P. Gianni
+++ Date Created: Summer 1988
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: GroebnerPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: groebner basis, polynomial ideals
+++ References:
+++ Description:
+++ Groebner functions for P F
+++   This package is an interface package to the groebner basis
+++ package which allows you to compute groebner bases for polynomials
+++ in either lexicographic ordering or total degree ordering refined
+++ by reverse lex. The input is the ordinary polynomial type which
+++ is internally converted to a type with the required ordering. 
+++ The resulting grobner basis is converted back to ordinary polynomials.
+++ The ordering among the variables is controlled by an explicit list
+++ of variables which is passed as a second argument. The coefficient
+++ domain is allowed to be any gcd domain, but the groebner basis is
+++ computed as if the polynomials were over a field.
+ 
+PolyGroebner(F) : C == T
+ 
+ where
+  F      :   GcdDomain
+  NNI    ==>  NonNegativeInteger
+  P      ==>  Polynomial F
+  L      ==>  List
+  E      ==>  Symbol
+ 
+  C == with
+     lexGroebner   :    (L P,L E)  ->  L P
+       ++ lexGroebner(lp,lv) computes Groebner basis
+       ++ for the list of polynomials lp in lexicographic order.
+       ++ The variables are ordered by their position in the list lv.
+ 
+     totalGroebner :    (L P, L E) ->  L P
+       ++ totalGroebner(lp,lv) computes Groebner basis
+       ++ for the list of polynomials lp with the terms
+       ++ ordered first by total degree and then
+       ++ refined by reverse lexicographic ordering.
+       ++ The variables are ordered by their position in the list lv.
+ 
+  T == add
+     lexGroebner(lp: L P,lv:L E) : L P ==
+       PP:=  PolToPol(lv,F)
+       DPoly := DistributedMultivariatePolynomial(lv,F)
+       DP:=DirectProduct(#lv,NNI)
+       OV:=OrderedVariableList lv
+       b:L DPoly:=[pToDmp(pol)$PP for pol in lp]
+       gb:L DPoly :=groebner(b)$GroebnerPackage(F,DP,OV,DPoly)
+       [dmpToP(pp)$PP for pp in gb]
+ 
+     totalGroebner(lp: L P,lv:L E) : L P ==
+       PP:=  PolToPol(lv,F)
+       HDPoly := HomogeneousDistributedMultivariatePolynomial(lv,F)
+       HDP:=HomogeneousDirectProduct(#lv,NNI)
+       OV:=OrderedVariableList lv
+       b:L HDPoly:=[pToHdmp(pol)$PP for pol in lp]
+       gb:=groebner(b)$GroebnerPackage(F,HDP,OV,HDPoly)
+       [hdmpToP(pp)$PP for pp in gb]
+
+@
+<<PGROEB.dotabb>>=
+"PGROEB" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PGROEB"]
+"FLAGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FLAGG"]
+"PGROEB" -> "FLAGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PAN2EXPR PolynomialAN2Expression}
 \pagehead{PolynomialAN2Expression}{PAN2EXPR}
 \pagepic{ps/v104polynomialan2expression.ps}{PAN2EXPR}{1.00}
@@ -57621,6 +62356,740 @@ PolynomialAN2Expression():Target == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package POLYLIFT PolynomialCategoryLifting}
+\pagehead{PolynomialCategoryLifting}{POLYLIFT}
+\pagepic{ps/v104polynomialcategorylifting.ps}{POLYLIFT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package POLYLIFT PolynomialCategoryLifting>>=
+)abbrev package POLYLIFT PolynomialCategoryLifting
+++ Author: Manuel Bronstein
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides a very general map function, which
+++ given a set S and polynomials over R with maps from the
+++ variables into S and the coefficients into S, maps polynomials
+++ into S. S is assumed to support \spad{+}, \spad{*} and \spad{**}.
+
+PolynomialCategoryLifting(E,Vars,R,P,S): Exports == Implementation where
+  E   : OrderedAbelianMonoidSup
+  Vars: OrderedSet
+  R   : Ring
+  P   : PolynomialCategory(R, E, Vars)
+  S   : SetCategory with
+           "+" : (%, %) -> %
+           "*" : (%, %) -> %
+           "**": (%, NonNegativeInteger) -> %
+
+  Exports ==> with
+    map: (Vars -> S, R -> S, P) -> S
+      ++ map(varmap, coefmap, p) takes a
+      ++ varmap, a mapping from the variables of polynomial p into S,
+      ++ coefmap, a mapping from coefficients of p into S, and p, and
+      ++ produces a member of S using the corresponding arithmetic.
+      ++ in S
+
+  Implementation ==> add
+    map(fv, fc, p) ==
+      (x1 := mainVariable p) case "failed" => fc leadingCoefficient p
+      up := univariate(p, x1::Vars)
+      t  := fv(x1::Vars)
+      ans:= fc 0
+      while not ground? up repeat
+        ans := ans + map(fv,fc, leadingCoefficient up) * t ** (degree up)
+        up  := reductum up
+      ans + map(fv, fc, leadingCoefficient up)
+
+@
+<<POLYLIFT.dotabb>>=
+"POLYLIFT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=POLYLIFT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"POLYLIFT" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PCOMP PolynomialComposition}
+\pagehead{PolynomialComposition}{PCOMP}
+\pagepic{ps/v104polynomialcomposition.ps}{PCOMP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+Polynomial composition and decomposition functions\\
+If f = g o h then  g = leftFactor(f, h)  and  h = rightFactor(f, g)
+<<package PCOMP PolynomialComposition>>=
+)abbrev package PCOMP PolynomialComposition
+++ Description:
+++ This package \undocumented
+PolynomialComposition(UP: UnivariatePolynomialCategory(R), R: Ring): with
+        compose: (UP, UP) -> UP
+		++ compose(p,q) \undocumented
+    == add
+        compose(g, h) ==
+            r: UP := 0
+            while g ^= 0 repeat
+                r := leadingCoefficient(g)*h**degree(g) + r
+                g := reductum g
+            r
+
+@
+<<PCOMP.dotabb>>=
+"PCOMP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PCOMP"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PCOMP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PDECOMP PolynomialDecomposition}
+\pagehead{PolynomialDecomposition}{PDECOMP}
+\pagepic{ps/v104polynomialdecomposition.ps}{PDECOMP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+Polynomial composition and decomposition functions\\
+If f = g o h then  g = leftFactor(f, h)  and  h = rightFactor(f, g)
+<<package PDECOMP PolynomialDecomposition>>=
+)abbrev package PDECOMP PolynomialDecomposition
+++ Description:
+++ This package \undocumented
+--  Ref: Kozen and Landau, Cornell University  TR 86-773
+PolynomialDecomposition(UP, F): PDcat == PDdef where
+    F:Field
+    UP:UnivariatePolynomialCategory F
+    NNI ==> NonNegativeInteger
+    LR  ==> Record(left: UP, right: UP)
+ 
+    PDcat == with
+        decompose: UP -> List UP
+		++ decompose(up) \undocumented
+        decompose: (UP, NNI, NNI) -> Union(LR, "failed")
+		++ decompose(up,m,n) \undocumented
+        leftFactor: (UP, UP) -> Union(UP, "failed") 
+		++ leftFactor(p,q) \undocumented
+        rightFactorCandidate:  (UP, NNI) -> UP
+		++ rightFactorCandidate(p,n) \undocumented
+    PDdef == add
+        leftFactor(f, h) ==
+             g: UP := 0
+             for i in 0.. while f ^= 0 repeat
+                 fr := divide(f, h)
+                 f := fr.quotient; r := fr.remainder
+                 degree r > 0 => return "failed"
+                 g := g + r * monomial(1, i)
+             g
+ 
+        decompose(f, dg, dh) ==
+            df := degree f
+            dg*dh ^= df => "failed"
+            h := rightFactorCandidate(f, dh)
+            g := leftFactor(f, h)
+            g case "failed" => "failed"
+            [g::UP, h]
+ 
+        decompose f ==
+            df := degree f
+            for dh in 2..df-1 | df rem dh = 0 repeat
+                h := rightFactorCandidate(f, dh)
+                g := leftFactor(f, h)
+                g case UP => return
+                    append(decompose(g::UP), decompose h)
+            [f]
+        rightFactorCandidate(f, dh) ==
+            f  := f/leadingCoefficient f
+            df := degree f
+            dg := df quo dh
+            h  := monomial(1, dh)
+            for k in 1..dh repeat
+                hdg:= h**dg
+                c  := (coefficient(f,(df-k)::NNI)-coefficient(hdg,(df-k)::NNI))/(dg::F)
+                h  := h + monomial(c, (dh-k)::NNI)
+            h - monomial(coefficient(h, 0), 0) -- drop constant term
+
+@
+<<PDECOMP.dotabb>>=
+"PDECOMP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PDECOMP"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PDECOMP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFBR PolynomialFactorizationByRecursion}
+\pagehead{PolynomialFactorizationByRecursion}{PFBR}
+\pagepic{ps/v104polynomialfactorizationbyrecursion.ps}{PFBR}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFBR PolynomialFactorizationByRecursion>>=
+)abbrev package PFBR PolynomialFactorizationByRecursion
+++ Description: PolynomialFactorizationByRecursion(R,E,VarSet,S)
+++ is used for factorization of sparse univariate polynomials over
+++ a domain S of multivariate polynomials over R.
+PolynomialFactorizationByRecursion(R,E, VarSet:OrderedSet, S): public ==
+ private where
+  R:PolynomialFactorizationExplicit
+  E:OrderedAbelianMonoidSup
+  S:PolynomialCategory(R,E,VarSet)
+  PI ==> PositiveInteger
+  SupR ==> SparseUnivariatePolynomial R
+  SupSupR ==> SparseUnivariatePolynomial SupR
+  SupS ==> SparseUnivariatePolynomial S
+  SupSupS ==> SparseUnivariatePolynomial SupS
+  LPEBFS ==> LinearPolynomialEquationByFractions(S)
+  public ==  with
+     solveLinearPolynomialEquationByRecursion: (List SupS, SupS)  ->
+                                                Union(List SupS,"failed")
+        ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
+        ++ returns the list of polynomials \spad{[q1,...,qn]}
+        ++ such that \spad{sum qi/pi = p / prod pi}, a
+        ++ recursion step for solveLinearPolynomialEquation
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{solveLinearPolynomialEquation}).
+        ++ If no such list of qi exists, then "failed" is returned.
+     factorByRecursion:  SupS -> Factored SupS
+        ++ factorByRecursion(p) factors polynomial p. This function
+        ++ performs the recursion step for factorPolynomial,
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{factorPolynomial})
+     factorSquareFreeByRecursion:  SupS -> Factored SupS
+        ++ factorSquareFreeByRecursion(p) returns the square free
+        ++ factorization of p. This functions performs
+        ++ the recursion step for factorSquareFreePolynomial,
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{factorSquareFreePolynomial}).
+     randomR: -> R  -- has to be global, since has alternative definitions
+        ++ randomR produces a random element of R
+     bivariateSLPEBR: (List SupS, SupS,  VarSet)  -> Union(List SupS,"failed")
+        ++ bivariateSLPEBR(lp,p,v) implements
+        ++ the bivariate case of
+        ++ \spadfunFrom{solveLinearPolynomialEquationByRecursion}{PolynomialFactorizationByRecursionUnivariate};
+        ++ its implementation depends on R
+     factorSFBRlcUnit: (List VarSet, SupS) -> Factored SupS
+        ++ factorSFBRlcUnit(p) returns the square free factorization of
+        ++ polynomial p
+        ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
+        ++ in the case where the leading coefficient of p
+        ++ is a unit.
+  private  == add
+   supR: SparseUnivariatePolynomial R
+   pp: SupS
+   lpolys,factors: List SupS
+   vv:VarSet
+   lvpolys,lvpp: List VarSet
+   r:R
+   lr:List R
+   import FactoredFunctionUtilities(SupS)
+   import FactoredFunctions2(S,SupS)
+   import FactoredFunctions2(SupR,SupS)
+   import CommuteUnivariatePolynomialCategory(S,SupS, SupSupS)
+   import UnivariatePolynomialCategoryFunctions2(S,SupS,SupS,SupSupS)
+   import UnivariatePolynomialCategoryFunctions2(SupS,SupSupS,S,SupS)
+   import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
+   import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
+   import UnivariatePolynomialCategoryFunctions2(S,SupS,SupR,SupSupR)
+   import UnivariatePolynomialCategoryFunctions2(SupR,SupSupR,S,SupS)
+   hensel: (SupS,VarSet,R,List SupS) ->
+           Union(Record(fctrs:List SupS),"failed")
+   chooseSLPEViableSubstitutions: (List VarSet,List SupS,SupS) ->
+    Record(substnsField:List R,lpolysRField:List SupR,ppRField:SupR)
+     --++ chooseSLPEViableSubstitutions(lv,lp,p) chooses substitutions
+     --++ for the variables in first arg (which are all
+     --++ the variables that exist) so that the polys in second argument don't
+     --++ drop in degree and remain square-free, and third arg doesn't drop
+     --++ drop in degree
+   chooseFSQViableSubstitutions: (List VarSet,SupS) ->
+    Record(substnsField:List R,ppRField:SupR)
+     --++ chooseFSQViableSubstitutions(lv,p) chooses substitutions for the variables in first arg (which are all
+     --++ the variables that exist) so that the second argument poly doesn't
+     --++ drop in degree and remains square-free
+   raise: SupR -> SupS
+   lower: SupS -> SupR
+   SLPEBR: (List SupS, List VarSet, SupS, List VarSet)  ->
+                                         Union(List SupS,"failed")
+   factorSFBRlcUnitInner: (List VarSet, SupS,R) ->
+                                         Union(Factored SupS,"failed")
+   hensel(pp,vv,r,factors) ==
+      origFactors:=factors
+      totdegree:Integer:=0
+      proddegree:Integer:=
+                   "max"/[degree(u,vv) for u in coefficients pp]
+      n:PI:=1
+      prime:=vv::S - r::S
+      foundFactors:List SupS:=empty()
+      while (totdegree <= proddegree) repeat
+          pn:=prime**n
+          Ecart:=(pp-*/factors) exquo  pn
+          Ecart case "failed" =>
+                error "failed lifting in hensel in PFBR"
+          zero? Ecart =>
+             -- then we have all the factors
+             return [append(foundFactors, factors)]
+          step:=solveLinearPolynomialEquation(origFactors,
+                                              map(eval(#1,vv,r),
+                                                  Ecart))
+          step case "failed" => return "failed" -- must be a false split
+          factors:=[a+b*pn for a in factors for b in step]
+          for a in factors for c in origFactors repeat
+              pp1:= pp exquo a
+              pp1 case "failed" => "next"
+              pp:=pp1
+              proddegree := proddegree - "max"/[degree(u,vv)
+                                                for u in coefficients a]
+              factors:=remove(a,factors)
+              origFactors:=remove(c,origFactors)
+              foundFactors:=[a,:foundFactors]
+          #factors < 2 =>
+             return [(empty? factors => foundFactors;
+                                     [pp,:foundFactors])]
+          totdegree:= +/["max"/[degree(u,vv)
+                                for u in coefficients u1]
+                         for u1 in factors]
+          n:=n+1
+      "failed" -- must have been a false split
+
+   factorSFBRlcUnitInner(lvpp,pp,r) ==
+      -- pp is square-free as a Sup, and its coefficients have precisely
+      -- the variables of lvpp. Furthermore, its LC is a unit
+      -- returns "failed" if the substitution is bad, else a factorization
+      ppR:=map(eval(#1,first lvpp,r),pp)
+      degree ppR < degree pp => "failed"
+      degree gcd(ppR,differentiate ppR) >0 => "failed"
+      factors:=
+         empty? rest lvpp =>
+            fDown:=factorSquareFreePolynomial map(retract(#1)::R,ppR)
+            [raise (unit fDown * factorList(fDown).first.fctr),
+             :[raise u.fctr for u in factorList(fDown).rest]]
+         fSame:=factorSFBRlcUnit(rest lvpp,ppR)
+         [unit fSame * factorList(fSame).first.fctr,
+          :[uu.fctr for uu in factorList(fSame).rest]]
+      #factors = 1 => makeFR(1,[["irred",pp,1]])
+      hen:=hensel(pp,first lvpp,r,factors)
+      hen case "failed" => "failed"
+      makeFR(1,[["irred",u,1] for u in hen.fctrs])
+   if R has StepThrough then
+     factorSFBRlcUnit(lvpp,pp) ==
+       val:R := init()
+       while true repeat
+          tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
+          not (tempAns case "failed") => return tempAns
+          val1:=nextItem val
+          val1 case "failed" =>
+            error "at this point, we know we have a finite field"
+          val:=val1
+   else
+     factorSFBRlcUnit(lvpp,pp) ==
+       val:R := randomR()
+       while true repeat
+          tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
+          not (tempAns case "failed") => return tempAns
+          val := randomR()
+   if R has random: -> R then
+      randomR() == random()
+   else randomR() == (random()$Integer)::R
+   if R has FiniteFieldCategory then
+     bivariateSLPEBR(lpolys,pp,v) ==
+       lpolysR:List SupSupR:=[map(univariate,u) for u in lpolys]
+       ppR: SupSupR:=map(univariate,pp)
+       ans:=solveLinearPolynomialEquation(lpolysR,ppR)$SupR
+       ans case "failed" => "failed"
+       [map(multivariate(#1,v),w) for w in ans]
+   else
+     bivariateSLPEBR(lpolys,pp,v) ==
+       solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+   chooseFSQViableSubstitutions(lvpp,pp) ==
+     substns:List R
+     ppR: SupR
+     while true repeat
+        substns:= [randomR() for v in lvpp]
+        zero? eval(leadingCoefficient pp,lvpp,substns ) => "next"
+        ppR:=map((retract eval(#1,lvpp,substns))::R,pp)
+        degree gcd(ppR,differentiate ppR)>0 => "next"
+        leave
+     [substns,ppR]
+   chooseSLPEViableSubstitutions(lvpolys,lpolys,pp) ==
+     substns:List R
+     lpolysR:List SupR
+     ppR: SupR
+     while true repeat
+        substns:= [randomR() for v in lvpolys]
+        zero? eval(leadingCoefficient pp,lvpolys,substns ) => "next"
+        "or"/[zero? eval(leadingCoefficient u,lvpolys,substns)
+                    for u in lpolys] => "next"
+        lpolysR:=[map((retract eval(#1,lvpolys,substns))::R,u)
+                  for u in lpolys]
+        uu:=lpolysR
+        while not empty? uu repeat
+          "or"/[ degree(gcd(uu.first,v))>0 for v in uu.rest] => leave
+          uu:=rest uu
+        not empty? uu => "next"
+        leave
+     ppR:=map((retract eval(#1,lvpolys,substns))::R,pp)
+     [substns,lpolysR,ppR]
+   raise(supR) == map(#1:R::S,supR)
+   lower(pp) == map(retract(#1)::R,pp)
+   SLPEBR(lpolys,lvpolys,pp,lvpp) ==
+     not empty? (m:=setDifference(lvpp,lvpolys)) =>
+         v:=first m
+         lvpp:=remove(v,lvpp)
+         pp1:SupSupS :=swap map(univariate(#1,v),pp)
+         -- pp1 is mathematically equal to pp, but is in S[z][v]
+         -- so we wish to operate on all of its coefficients
+         ans:List SupSupS:= [0 for u in lpolys]
+         for m in reverse_! monomials pp1 repeat
+             ans1:=SLPEBR(lpolys,lvpolys,leadingCoefficient m,lvpp)
+             ans1 case "failed" => return "failed"
+             d:=degree m
+             ans:=[monomial(a1,d)+a for a in ans for a1 in ans1]
+         [map(multivariate(#1,v),swap pp1) for pp1 in ans]
+     empty? lvpolys =>
+         lpolysR:List SupR
+         ppR:SupR
+         lpolysR:=[map(retract,u) for u in lpolys]
+         ppR:=map(retract,pp)
+         ansR:=solveLinearPolynomialEquation(lpolysR,ppR)
+         ansR case "failed" => return "failed"
+         [map(#1::S,uu) for uu in ansR]
+     cVS:=chooseSLPEViableSubstitutions(lvpolys,lpolys,pp)
+     ansR:=solveLinearPolynomialEquation(cVS.lpolysRField,cVS.ppRField)
+     ansR case "failed" => "failed"
+     #lvpolys = 1 => bivariateSLPEBR(lpolys,pp, first lvpolys)
+     solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+
+   solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
+     lvpolys := removeDuplicates_!
+                  concat [ concat [variables z for z in coefficients u]
+                                               for u in lpolys]
+     lvpp := removeDuplicates_!
+                concat [variables z for z in coefficients pp]
+     SLPEBR(lpolys,lvpolys,pp,lvpp)
+
+   factorByRecursion pp ==
+     lv:List(VarSet) := removeDuplicates_!
+                           concat [variables z for z in coefficients pp]
+     empty? lv =>
+         map(raise,factorPolynomial lower pp)
+     c:=content pp
+     unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
+     pp:=(pp exquo c)::SupS
+     mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
+                  map(#1:S::SupS,factor(c)$S))
+   factorSquareFreeByRecursion pp ==
+     lv:List(VarSet) := removeDuplicates_!
+                           concat [variables z for z in coefficients pp]
+     empty? lv =>
+         map(raise,factorPolynomial lower pp)
+     unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(lv,pp)
+     oldnfact:NonNegativeInteger:= 999999
+                       -- I hope we never have to factor a polynomial
+                       -- with more than this number of factors
+     lcppPow:S
+     while true repeat
+       cVS:=chooseFSQViableSubstitutions(lv,pp)
+       factorsR:=factorSquareFreePolynomial(cVS.ppRField)
+       (nfact:=numberOfFactors factorsR) = 1 =>
+                  return makeFR(1,[["irred",pp,1]])
+       -- OK, force all leading coefficients to be equal to the leading
+       -- coefficient of the input
+       nfact > oldnfact => "next"   -- can't be a good reduction
+       oldnfact:=nfact
+       factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
+                  for u in factorList factorsR]
+       ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
+       lvppList:=lv
+       OK:=true
+       for u in lvppList for v in cVS.substnsField repeat
+           hen:=hensel(ppAdjust,u,v,factors)
+           hen case "failed" =>
+               OK:=false
+               "leave"
+           factors:=hen.fctrs
+       OK => leave
+     factors:=[ (lc:=content w;
+                 lcppPow:=(lcppPow exquo lc)::S;
+                  (w exquo lc)::SupS)
+                for w in factors]
+     not unit? lcppPow =>
+         error "internal error in factorSquareFreeByRecursion"
+     makeFR((recip lcppPow)::S::SupS,
+             [["irred",w,1] for w in factors])
+
+@
+<<PFBR.dotabb>>=
+"PFBR" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFBR"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PFBR" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PFBRU PolynomialFactorizationByRecursionUnivariate}
+\pagehead{PolynomialFactorizationByRecursionUnivariate}{PFBRU}
+\pagepic{ps/v104polynomialfactorizationbyrecursionunivariate.ps}{PFBRU}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PFBRU PolynomialFactorizationByRecursionUnivariate>>=
+)abbrev package PFBRU PolynomialFactorizationByRecursionUnivariate
+++ PolynomialFactorizationByRecursionUnivariate
+++ R is a \spadfun{PolynomialFactorizationExplicit} domain,
+++ S is univariate polynomials over R
+++ We are interested in handling SparseUnivariatePolynomials over
+++ S, is a variable we shall call z
+PolynomialFactorizationByRecursionUnivariate(R, S): public == private where
+  R:PolynomialFactorizationExplicit
+  S:UnivariatePolynomialCategory(R)
+  PI ==> PositiveInteger
+  SupR ==> SparseUnivariatePolynomial R
+  SupSupR ==> SparseUnivariatePolynomial SupR
+  SupS ==> SparseUnivariatePolynomial S
+  SupSupS ==> SparseUnivariatePolynomial SupS
+  LPEBFS ==> LinearPolynomialEquationByFractions(S)
+  public ==  with
+     solveLinearPolynomialEquationByRecursion: (List SupS, SupS)  ->
+                                               Union(List SupS,"failed")
+        ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
+        ++ returns the list of polynomials \spad{[q1,...,qn]}
+        ++ such that \spad{sum qi/pi = p / prod pi}, a
+        ++ recursion step for solveLinearPolynomialEquation
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{solveLinearPolynomialEquation}).
+        ++ If no such list of qi exists, then "failed" is returned.
+     factorByRecursion:  SupS -> Factored SupS
+        ++ factorByRecursion(p) factors polynomial p. This function
+        ++ performs the recursion step for factorPolynomial,
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{factorPolynomial})
+     factorSquareFreeByRecursion:  SupS -> Factored SupS
+        ++ factorSquareFreeByRecursion(p) returns the square free
+        ++ factorization of p. This functions performs
+        ++ the recursion step for factorSquareFreePolynomial,
+        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+        ++ (see \spadfun{factorSquareFreePolynomial}).
+     randomR: -> R  -- has to be global, since has alternative definitions
+        ++ randomR() produces a random element of R
+     factorSFBRlcUnit: (SupS) -> Factored SupS
+        ++ factorSFBRlcUnit(p) returns the square free factorization of
+        ++ polynomial p
+        ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
+        ++ in the case where the leading coefficient of p
+        ++ is a unit.
+  private  == add
+   supR: SparseUnivariatePolynomial R
+   pp: SupS
+   lpolys,factors: List SupS
+   r:R
+   lr:List R
+   import FactoredFunctionUtilities(SupS)
+   import FactoredFunctions2(SupR,SupS)
+   import FactoredFunctions2(S,SupS)
+   import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
+   import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
+   -- local function declarations
+   raise: SupR -> SupS
+   lower: SupS -> SupR
+   factorSFBRlcUnitInner: (SupS,R) -> Union(Factored SupS,"failed")
+   hensel: (SupS,R,List SupS) ->
+           Union(Record(fctrs:List SupS),"failed")
+   chooseFSQViableSubstitutions: (SupS) ->
+    Record(substnsField:R,ppRField:SupR)
+     --++ chooseFSQViableSubstitutions(p), p is a sup
+     --++ ("sparse univariate polynomial")
+     --++ over a sup over R, returns a record
+     --++ \spad{[substnsField: r, ppRField: q]} where r is a substitution point
+     --++ q is a sup over R so that the (implicit) variable in q
+     --++ does not drop in degree and remains square-free.
+   -- here for the moment, until it compiles
+   -- N.B., we know that R is NOT a FiniteField, since
+   -- that is meant to have a special implementation, to break the
+   -- recursion
+   solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
+     lhsdeg:="max"/["max"/[degree v for v in coefficients u] for u in lpolys]
+     rhsdeg:="max"/[degree v for v in coefficients pp]
+     lhsdeg = 0 =>
+       lpolysLower:=[lower u for u in lpolys]
+       answer:List SupS := [0 for u in lpolys]
+       for i in 0..rhsdeg repeat
+         ppx:=map(coefficient(#1,i),pp)
+         zero? ppx => "next"
+         recAns:= solveLinearPolynomialEquation(lpolysLower,ppx)
+         recAns case "failed" => return "failed"
+         answer:=[monomial(1,i)$S * raise c + d
+                    for c in recAns for d in answer]
+       answer
+     solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+   -- local function definitions
+   hensel(pp,r,factors) ==
+      -- factors is a relatively prime factorization of pp modulo the ideal
+      -- (x-r), with suitably imposed leading coefficients.
+      -- This is lifted, without re-combinations, to a factorization
+      -- return "failed" if this can't be done
+      origFactors:=factors
+      totdegree:Integer:=0
+      proddegree:Integer:=
+                   "max"/[degree(u) for u in coefficients pp]
+      n:PI:=1
+      pn:=prime:=monomial(1,1) - r::S
+      foundFactors:List SupS:=empty()
+      while (totdegree <= proddegree) repeat
+          Ecart:=(pp-*/factors) exquo  pn
+          Ecart case "failed" =>
+                error "failed lifting in hensel in PFBRU"
+          zero? Ecart =>
+             -- then we have all the factors
+             return [append(foundFactors, factors)]
+          step:=solveLinearPolynomialEquation(origFactors,
+                                              map(elt(#1,r::S),
+                                                  Ecart))
+          step case "failed" => return "failed" -- must be a false split
+          factors:=[a+b*pn for a in factors for b in step]
+          for a in factors for c in origFactors repeat
+              pp1:= pp exquo a
+              pp1 case "failed" => "next"
+              pp:=pp1
+              proddegree := proddegree - "max"/[degree(u)
+                                                for u in coefficients a]
+              factors:=remove(a,factors)
+              origFactors:=remove(c,origFactors)
+              foundFactors:=[a,:foundFactors]
+          #factors < 2 =>
+             return [(empty? factors => foundFactors;
+                                     [pp,:foundFactors])]
+          totdegree:= +/["max"/[degree(u)
+                                for u in coefficients u1]
+                         for u1 in factors]
+          n:=n+1
+          pn:=pn*prime
+      "failed" -- must have been a false split
+   chooseFSQViableSubstitutions(pp) ==
+     substns:R
+     ppR: SupR
+     while true repeat
+        substns:= randomR()
+        zero? elt(leadingCoefficient pp,substns ) => "next"
+        ppR:=map( elt(#1,substns),pp)
+        degree gcd(ppR,differentiate ppR)>0 => "next"
+        leave
+     [substns,ppR]
+   raise(supR) == map(#1:R::S,supR)
+   lower(pp) == map(retract(#1)::R,pp)
+   factorSFBRlcUnitInner(pp,r) ==
+      -- pp is square-free as a Sup, but the Up  variable occurs.
+      -- Furthermore, its LC is a unit
+      -- returns "failed" if the substitution is bad, else a factorization
+      ppR:=map(elt(#1,r),pp)
+      degree ppR < degree pp => "failed"
+      degree gcd(ppR,differentiate ppR) >0 => "failed"
+      factors:=
+        fDown:=factorSquareFreePolynomial ppR
+        [raise (unit fDown * factorList(fDown).first.fctr),
+         :[raise u.fctr for u in factorList(fDown).rest]]
+      #factors = 1 => makeFR(1,[["irred",pp,1]])
+      hen:=hensel(pp,r,factors)
+      hen case "failed" => "failed"
+      makeFR(1,[["irred",u,1] for u in hen.fctrs])
+   -- exported function definitions
+   if R has StepThrough then
+     factorSFBRlcUnit(pp) ==
+       val:R := init()
+       while true repeat
+          tempAns:=factorSFBRlcUnitInner(pp,val)
+          not (tempAns case "failed") => return tempAns
+          val1:=nextItem val
+          val1 case "failed" =>
+            error "at this point, we know we have a finite field"
+          val:=val1
+   else
+     factorSFBRlcUnit(pp) ==
+       val:R := randomR()
+       while true repeat
+          tempAns:=factorSFBRlcUnitInner(pp,val)
+          not (tempAns case "failed") => return tempAns
+          val := randomR()
+   if R has StepThrough then
+      randomCount:R:= init()
+      randomR() ==
+        v:=nextItem(randomCount)
+        v case "failed" =>
+          SAY$Lisp "Taking another set of random values"
+          randomCount:=init()
+          randomCount
+        randomCount:=v
+        randomCount
+   else if R has random: -> R then
+      randomR() == random()
+   else randomR() == (random()$Integer rem 100)::R
+   factorByRecursion pp ==
+     and/[zero? degree u for u in coefficients pp] =>
+         map(raise,factorPolynomial lower pp)
+     c:=content pp
+     unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
+     pp:=(pp exquo c)::SupS
+     mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
+                  map(#1:S::SupS,factor(c)$S))
+   factorSquareFreeByRecursion pp ==
+     and/[zero? degree u for u in coefficients pp] =>
+        map(raise,factorSquareFreePolynomial lower pp)
+     unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(pp)
+     oldnfact:NonNegativeInteger:= 999999
+                       -- I hope we never have to factor a polynomial
+                       -- with more than this number of factors
+     lcppPow:S
+     while true repeat  -- a loop over possible false splits
+       cVS:=chooseFSQViableSubstitutions(pp)
+       newppR:=primitivePart cVS.ppRField
+       factorsR:=factorSquareFreePolynomial(newppR)
+       (nfact:=numberOfFactors factorsR) = 1 =>
+                  return makeFR(1,[["irred",pp,1]])
+       -- OK, force all leading coefficients to be equal to the leading
+       -- coefficient of the input
+       nfact > oldnfact => "next"   -- can't be a good reduction
+       oldnfact:=nfact
+       lcppR:=leadingCoefficient cVS.ppRField
+       factors:=[raise((lcppR exquo leadingCoefficient u.fctr) ::R * u.fctr)
+                  for u in factorList factorsR]
+       -- factors now multiplies to give cVS.ppRField * lcppR^(#factors-1)
+       -- Now change the leading coefficient to be lcpp
+       factors:=[monomial(lcpp,degree u) + reductum u for u in factors]
+--     factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
+--                for u in factorList factorsR]
+       ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
+       OK:=true
+       hen:=hensel(ppAdjust,cVS.substnsField,factors)
+       hen case "failed" => "next"
+       factors:=hen.fctrs
+       leave
+     factors:=[ (lc:=content w;
+                 lcppPow:=(lcppPow exquo lc)::S;
+                  (w exquo lc)::SupS)
+                for w in factors]
+     not unit? lcppPow =>
+         error "internal error in factorSquareFreeByRecursion"
+     makeFR((recip lcppPow)::S::SupS,
+             [["irred",w,1] for w in factors])
+
+@
+<<PFBRU.dotabb>>=
+"PFBRU" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PFBRU"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PFBRU" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package POLY2 PolynomialFunctions2}
 \pagehead{PolynomialFunctions2}{POLY2}
 \pagepic{ps/v104polynomialfunctions2.ps}{POLY2}{1.00}
@@ -57662,6 +63131,494 @@ PolynomialFunctions2(R:Ring, S:Ring): with
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PGCD PolynomialGcdPackage}
+\pagehead{PolynomialGcdPackage}{PGCD}
+\pagepic{ps/v104polynomialgcdpackage.ps}{PGCD}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PGCD PolynomialGcdPackage>>=
+)abbrev package PGCD PolynomialGcdPackage
+++ Author: Michael Lucks, P. Gianni
+++ Date Created:
+++ Date Last Updated: 17 June 1996
+++ Fix History: Moved unitCanonicals for performance (BMT);
+++              Fixed a problem with gcd(x,0) (Frederic Lehobey)
+++ Basic Functions: gcd, content
+++ Related Constructors: Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++   This package computes multivariate polynomial gcd's using
+++ a hensel lifting strategy. The contraint on the coefficient
+++ domain is imposed by the lifting strategy. It is assumed that
+++ the coefficient domain has the property that almost all specializations
+++ preserve the degree of the gcd.
+ 
+I        ==> Integer
+NNI      ==> NonNegativeInteger
+PI       ==> PositiveInteger
+ 
+PolynomialGcdPackage(E,OV,R,P):C == T where
+    R     :  EuclideanDomain
+    P     :  PolynomialCategory(R,E,OV)
+    OV    :  OrderedSet
+    E     :  OrderedAbelianMonoidSup
+ 
+    SUPP      ==> SparseUnivariatePolynomial P
+ 
+    C == with
+      gcd               :   (P,P)    -> P
+        ++ gcd(p,q) computes the gcd of the two polynomials p and q.
+      gcd               :   List P   -> P
+        ++ gcd(lp) computes the gcd of the list of polynomials lp.
+      gcd               :   (SUPP,SUPP)    -> SUPP
+        ++ gcd(p,q) computes the gcd of the two polynomials p and q.
+      gcd               :   List SUPP   -> SUPP
+        ++ gcd(lp) computes the gcd of the list of polynomials lp.
+      gcdPrimitive      :   (P,P)    -> P
+        ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
+        ++ p and q.
+      gcdPrimitive      :   (SUPP,SUPP)    -> SUPP
+        ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
+        ++ p and q.
+      gcdPrimitive      :   List P   -> P
+        ++ gcdPrimitive lp computes the gcd of the list of primitive
+        ++ polynomials lp.
+
+    T == add
+ 
+      SUP      ==> SparseUnivariatePolynomial R
+ 
+      LGcd     ==> Record(locgcd:SUPP,goodint:List List R)
+      UTerm    ==> Record(lpol:List SUP,lint:List List R,mpol:SUPP)
+      pmod:R   :=  (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
+ 
+      import MultivariateLifting(E,OV,R,P)
+      import FactoringUtilities(E,OV,R,P)
+ 
+                 --------  Local  Functions  --------
+ 
+      myran           :    Integer   -> Union(R,"failed")
+      better          :    (P,P)     -> Boolean
+      failtest        :   (SUPP,SUPP,SUPP)    -> Boolean
+      monomContent    :   (SUPP)   -> SUPP
+      gcdMonom        :  (SUPP,SUPP)    -> SUPP
+      gcdTermList     :    (P,P)     -> P
+      good            :  (SUPP,List OV,List List R) -> Record(upol:SUP,inval:List List R)
+ 
+      chooseVal       :  (SUPP,SUPP,List OV,List List R) -> Union(UTerm,"failed")
+      localgcd        :  (SUPP,SUPP,List OV,List List R) -> LGcd
+      notCoprime      :  (SUPP,SUPP, List NNI,List OV,List List R)   -> SUPP
+      imposelc        : (List SUP,List OV,List R,List P) -> List SUP
+ 
+      lift? :(SUPP,SUPP,UTerm,List NNI,List OV) -> Union(s:SUPP,failed:"failed",notCoprime:"notCoprime")
+      lift  :(SUPP,SUP,SUP,P,List OV,List NNI,List R) -> Union(SUPP,"failed")
+ 
+                     ---- Local  functions ----
+    -- test if something wrong happened in the gcd
+      failtest(f:SUPP,p1:SUPP,p2:SUPP) : Boolean ==
+        (p1 exquo f) case "failed" or (p2 exquo f) case "failed"
+ 
+    -- Choose the integers
+      chooseVal(p1:SUPP,p2:SUPP,lvr:List OV,ltry:List List R):Union(UTerm,"failed") ==
+        d1:=degree(p1)
+        d2:=degree(p2)
+        dd:NNI:=0$NNI
+        nvr:NNI:=#lvr
+        lval:List R :=[]
+        range:I:=8
+        repeat
+          range:=2*range
+          lval:=[ran(range) for i in 1..nvr]
+          member?(lval,ltry) => "new point"
+          ltry:=cons(lval,ltry)
+          uf1:SUP:=completeEval(p1,lvr,lval)
+          degree uf1 ^= d1 => "new point"
+          uf2:SUP:= completeEval(p2,lvr,lval)
+          degree uf2 ^= d2 => "new point"
+          u:=gcd(uf1,uf2)
+          du:=degree u
+         --the univariate gcd is 1
+          if du=0 then return [[1$SUP],ltry,0$SUPP]$UTerm
+ 
+          ugcd:List SUP:=[u,(uf1 exquo u)::SUP,(uf2 exquo u)::SUP]
+          uterm:=[ugcd,ltry,0$SUPP]$UTerm
+          dd=0 => dd:=du
+ 
+        --the degree is not changed
+          du=dd =>
+ 
+           --test if one of the polynomials is the gcd
+            dd=d1 =>
+              if ^((f:=p2 exquo p1) case "failed") then
+                return [[u],ltry,p1]$UTerm
+              if dd^=d2 then dd:=(dd-1)::NNI
+ 
+            dd=d2 =>
+              if ^((f:=p1 exquo p2) case "failed") then
+                return [[u],ltry,p2]$UTerm
+              dd:=(dd-1)::NNI
+            return uterm
+ 
+         --the new gcd has degree less
+          du<dd => dd:=du
+ 
+      good(f:SUPP,lvr:List OV,ltry:List List R):Record(upol:SUP,inval:List List R) ==
+        nvr:NNI:=#lvr
+        range:I:=1
+        while true repeat
+          range:=2*range
+          lval:=[ran(range) for i in 1..nvr]
+          member?(lval,ltry) => "new point"
+          ltry:=cons(lval,ltry)
+          uf:=completeEval(f,lvr,lval)
+          if degree gcd(uf,differentiate uf)=0 then return [uf,ltry]
+ 
+      -- impose the right lc
+      imposelc(lipol:List SUP,
+               lvar:List OV,lval:List R,leadc:List P):List SUP ==
+        result:List SUP :=[]
+        for pol in lipol for leadpol in leadc repeat
+           p1:= univariate eval(leadpol,lvar,lval) * pol
+           result:= cons((p1 exquo leadingCoefficient pol)::SUP,result)
+        reverse result
+ 
+    --Compute the gcd between not coprime polynomials
+      notCoprime(g:SUPP,p2:SUPP,ldeg:List NNI,lvar1:List OV,ltry:List List R) : SUPP ==
+        g1:=gcd(g,differentiate g)
+        l1 := (g exquo g1)::SUPP
+        lg:LGcd:=localgcd(l1,p2,lvar1,ltry)
+        (l,ltry):=(lg.locgcd,lg.goodint)
+        lval:=ltry.first
+        p2l:=(p2 exquo l)::SUPP
+        (gd1,gd2):=(l,l)
+        ul:=completeEval(l,lvar1,lval)
+        dl:=degree ul
+        if degree gcd(ul,differentiate ul) ^=0 then
+          newchoice:=good(l,lvar1,ltry)
+          ul:=newchoice.upol
+          ltry:=newchoice.inval
+          lval:=ltry.first
+        ug1:=completeEval(g1,lvar1,lval)
+        ulist:=[ug1,completeEval(p2l,lvar1,lval)]
+        lcpol:List P:=[leadingCoefficient g1, leadingCoefficient p2]
+        while true repeat
+          d:SUP:=gcd(cons(ul,ulist))
+          if degree d =0 then return gd1
+          lquo:=(ul exquo d)::SUP
+          if degree lquo ^=0 then
+            lgcd:=gcd(cons(leadingCoefficient l,lcpol))
+            (gdl:=lift(l,d,lquo,lgcd,lvar1,ldeg,lval)) case "failed" =>
+               return notCoprime(g,p2,ldeg,lvar1,ltry)
+            l:=gd2:=gdl::SUPP
+            ul:=completeEval(l,lvar1,lval)
+            dl:=degree ul
+          gd1:=gd1*gd2
+          ulist:=[(uf exquo d)::SUP for uf in ulist]
+ 
+      gcdPrimitive(p1:SUPP,p2:SUPP) : SUPP ==
+        if (d1:=degree(p1)) > (d2:=degree(p2)) then
+            (p1,p2):= (p2,p1)
+            (d1,d2):= (d2,d1)
+        degree p1 = 0 =>
+            p1 = 0 => unitCanonical p2
+            unitCanonical p1
+        lvar:List OV:=sort(#1>#2,setUnion(variables p1,variables p2))
+        empty? lvar =>
+           raisePolynomial(gcd(lowerPolynomial p1,lowerPolynomial p2))
+        (p2 exquo p1) case SUPP => unitCanonical p1
+        ltry:List List R:=empty()
+        totResult:=localgcd(p1,p2,lvar,ltry)
+        result: SUPP:=totResult.locgcd
+        -- special cases
+        result=1 => 1$SUPP
+        while failtest(result,p1,p2) repeat
+--        SAY$Lisp  "retrying gcd"
+          ltry:=totResult.goodint
+          totResult:=localgcd(p1,p2,lvar,ltry)
+          result:=totResult.locgcd
+        result
+ 
+    --local function for the gcd : it returns the evaluation point too
+      localgcd(p1:SUPP,p2:SUPP,lvar:List(OV),ltry:List List R) : LGcd ==
+        uterm:=chooseVal(p1,p2,lvar,ltry)::UTerm
+        ltry:=uterm.lint
+        listpol:= uterm.lpol
+        ud:=listpol.first
+        dd:= degree ud
+ 
+        --the univariate gcd is 1
+        dd=0 => [1$SUPP,ltry]$LGcd
+ 
+        --one of the polynomials is the gcd
+        dd=degree(p1) or dd=degree(p2) =>
+                         [uterm.mpol,ltry]$LGcd
+        ldeg:List NNI:=map(min,degree(p1,lvar),degree(p2,lvar))
+ 
+       -- if there is a polynomial g s.t. g/gcd and gcd are coprime ...
+        -- I can lift
+        (h:=lift?(p1,p2,uterm,ldeg,lvar)) case notCoprime =>
+          [notCoprime(p1,p2,ldeg,lvar,ltry),ltry]$LGcd
+        h case failed => localgcd(p1,p2,lvar,ltry) -- skip bad values?
+        [h.s,ltry]$LGcd
+ 
+ 
+  -- content, internal functions return the poly if it is a monomial
+      monomContent(p:SUPP):SUPP ==
+        degree(p)=0 => 1
+        md:= minimumDegree(p)
+        monomial(gcd sort(better,coefficients p),md)
+ 
+  -- Ordering for gcd purposes
+      better(p1:P,p2:P):Boolean ==
+        ground? p1 => true
+        ground? p2 => false
+        degree(p1,mainVariable(p1)::OV) < degree(p2,mainVariable(p2)::OV)
+ 
+  -- Gcd between polynomial p1 and p2 with
+  -- mainVariable p1 < x=mainVariable p2
+      gcdTermList(p1:P,p2:P) : P ==
+        termList:=sort(better,
+           cons(p1,coefficients univariate(p2,(mainVariable p2)::OV)))
+        q:P:=termList.first
+        for term in termList.rest until q = 1$P repeat q:= gcd(q,term)
+        q
+ 
+  -- Gcd between polynomials with the same mainVariable
+      gcd(p1:SUPP,p2:SUPP): SUPP ==
+        if degree(p1) > degree(p2) then (p1,p2):= (p2,p1)
+        degree p1 = 0 =>
+           p1 = 0 => unitCanonical p2
+           p1 = 1 => unitCanonical p1
+           gcd(leadingCoefficient p1, content p2)::SUPP
+        reductum(p1)=0 => gcdMonom(p1,monomContent p2)
+        c1:= monomContent(p1)
+        reductum(p2)=0 => gcdMonom(c1,p2)
+        c2:= monomContent(p2)
+        p1:= (p1 exquo c1)::SUPP
+        p2:= (p2 exquo c2)::SUPP
+        gcdPrimitive(p1,p2) * gcdMonom(c1,c2)
+ 
+   -- gcd between 2 monomials
+      gcdMonom(m1:SUPP,m2:SUPP):SUPP ==
+        monomial(gcd(leadingCoefficient(m1),leadingCoefficient(m2)),
+                 min(degree(m1),degree(m2)))
+
+ 
+    --If there is a pol s.t. pol/gcd and gcd are coprime I can lift
+      lift?(p1:SUPP,p2:SUPP,uterm:UTerm,ldeg:List NNI,
+                     lvar:List OV) : Union(s:SUPP,failed:"failed",notCoprime:"notCoprime") ==
+        leadpol:Boolean:=false
+        (listpol,lval):=(uterm.lpol,uterm.lint.first)
+        d:=listpol.first
+        listpol:=listpol.rest
+        nolift:Boolean:=true
+        for uf in listpol repeat
+              --note uf and d not necessarily primitive
+          degree gcd(uf,d) =0 => nolift:=false
+        nolift => ["notCoprime"]
+        f:SUPP:=([p1,p2]$List(SUPP)).(position(uf,listpol))
+        lgcd:=gcd(leadingCoefficient p1, leadingCoefficient p2)
+        (l:=lift(f,d,uf,lgcd,lvar,ldeg,lval)) case "failed" => ["failed"]
+        [l :: SUPP]
+ 
+   -- interface with the general "lifting" function
+      lift(f:SUPP,d:SUP,uf:SUP,lgcd:P,lvar:List OV,
+                        ldeg:List NNI,lval:List R):Union(SUPP,"failed") ==
+        leadpol:Boolean:=false
+        lcf:P
+        lcf:=leadingCoefficient f
+        df:=degree f
+        leadlist:List(P):=[]
+ 
+        if lgcd^=1 then
+          leadpol:=true
+          f:=lgcd*f
+          ldeg:=[n0+n1 for n0 in ldeg for n1 in degree(lgcd,lvar)]
+          lcd:R:=leadingCoefficient d
+          if degree(lgcd)=0 then d:=((retract lgcd) *d exquo lcd)::SUP
+          else d:=(retract(eval(lgcd,lvar,lval)) * d exquo lcd)::SUP
+          uf:=lcd*uf
+        leadlist:=[lgcd,lcf]
+        lg:=imposelc([d,uf],lvar,lval,leadlist)
+        (pl:=lifting(f,lvar,lg,lval,leadlist,ldeg,pmod)) case "failed" =>
+               "failed"
+        plist := pl :: List SUPP
+        (p0:SUPP,p1:SUPP):=(plist.first,plist.2)
+        if completeEval(p0,lvar,lval) ^= lg.first then
+           (p0,p1):=(p1,p0)
+        ^leadpol => p0
+        p0 exquo content(p0)
+ 
+  -- Gcd for two multivariate polynomials
+      gcd(p1:P,p2:P) : P ==
+        ground? p1 =>
+          p1 := unitCanonical p1
+          p1 = 1$P => p1
+          p1 = 0$P => unitCanonical p2
+          ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+          gcdTermList(p1,p2)
+        ground? p2 =>
+          p2 := unitCanonical p2
+          p2 = 1$P => p2
+          p2 = 0$P => unitCanonical p1
+          gcdTermList(p2,p1)
+        (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
+        mv1:= mainVariable(p1)::OV
+        mv2:= mainVariable(p2)::OV
+        mv1 = mv2 => multivariate(gcd(univariate(p1,mv1),
+                                      univariate(p2,mv1)),mv1)
+        mv1 < mv2 => gcdTermList(p1,p2)
+        gcdTermList(p2,p1)
+ 
+  -- Gcd for a list of multivariate polynomials
+      gcd(listp:List P) : P ==
+        lf:=sort(better,listp)
+        f:=lf.first
+        for g in lf.rest repeat
+          f:=gcd(f,g)
+          if f=1$P then return f
+        f
+
+      gcd(listp:List SUPP) : SUPP ==
+        lf:=sort(degree(#1)<degree(#2),listp)
+        f:=lf.first
+        for g in lf.rest repeat
+          f:=gcd(f,g)
+          if f=1 then return f
+        f
+
+ 
+   -- Gcd for primitive polynomials
+      gcdPrimitive(p1:P,p2:P):P ==
+        (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
+        ground? p1 =>
+          ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+          p1 = 0$P => p2
+          1$P
+        ground? p2 =>
+          p2 = 0$P => p1
+          1$P
+        mv1:= mainVariable(p1)::OV
+        mv2:= mainVariable(p2)::OV
+        mv1 = mv2 =>
+          md:=min(minimumDegree(p1,mv1),minimumDegree(p2,mv2))
+          mp:=1$P
+          if md>1 then
+            mp:=(mv1::P)**md
+            p1:=(p1 exquo mp)::P
+            p2:=(p2 exquo mp)::P
+          up1 := univariate(p1,mv1)
+          up2 := univariate(p2,mv2)
+          mp*multivariate(gcdPrimitive(up1,up2),mv1)
+        1$P
+ 
+  -- Gcd for a list of primitive multivariate polynomials
+      gcdPrimitive(listp:List P) : P ==
+        lf:=sort(better,listp)
+        f:=lf.first
+        for g in lf.rest repeat
+          f:=gcdPrimitive(f,g)
+          if f=1$P then return f
+        f
+
+@
+<<PGCD.dotabb>>=
+"PGCD" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PGCD"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PGCD" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PINTERP PolynomialInterpolation}
+\pagehead{PolynomialInterpolation}{PINTERP}
+\pagepic{ps/v104polynomialinterpolation.ps}{PINTERP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PINTERP PolynomialInterpolation>>=
+)abbrev package PINTERP PolynomialInterpolation
+++ Description:
+++ This package exports interpolation algorithms
+PolynomialInterpolation(xx, F): Cat == Body   where
+    xx: Symbol
+    F:  Field
+    UP  ==> UnivariatePolynomial
+    SUP ==> SparseUnivariatePolynomial
+ 
+    Cat ==> with
+        interpolate: (UP(xx,F), List F, List F) -> UP(xx,F)
+		++ interpolate(u,lf,lg) \undocumented
+        interpolate: (List F, List F)           -> SUP F
+		++ interpolate(lf,lg) \undocumented
+ 
+    Body ==> add
+        PIA ==> PolynomialInterpolationAlgorithms
+ 
+        interpolate(qx, lx, ly) ==
+            px := LagrangeInterpolation(lx, ly)$PIA(F, UP(xx, F))
+            elt(px, qx)
+ 
+        interpolate(lx, ly) ==
+            LagrangeInterpolation(lx, ly)$PIA(F, SUP F)
+
+@
+<<PINTERP.dotabb>>=
+"PINTERP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PINTERP"]
+"FIELD"  [color="#4488FF",href="bookvol10.2.pdf#nameddest=FIELD"]
+"PINTERP" -> "FIELD"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PINTERPA PolynomialInterpolationAlgorithms}
+\pagehead{PolynomialInterpolationAlgorithms}{PINTERPA}
+\pagepic{ps/v104polynomialinterpolationalgorithms.ps}{PINTERPA}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PINTERPA PolynomialInterpolationAlgorithms>>=
+)abbrev package PINTERPA PolynomialInterpolationAlgorithms
+++ Description:
+++ This package exports interpolation algorithms
+PolynomialInterpolationAlgorithms(F, P): Cat == Body   where
+    F: Field
+    P: UnivariatePolynomialCategory(F)
+ 
+    Cat ==> with
+        LagrangeInterpolation: (List F, List F) -> P
+		++ LagrangeInterpolation(l1,l2) \undocumented
+ 
+    Body ==> add
+        LagrangeInterpolation(lx, ly) ==
+            #lx ^= #ly =>
+                error "Different number of points and values."
+            ip: P := 0
+            for xi in lx for yi in ly for i in 0.. repeat
+                pp: P := 1
+                xp: F := 1
+                for xj in lx for j in 0.. | i ^= j repeat
+                    pp := pp * (monomial(1,1) - monomial(xj,0))
+                    xp := xp * (xi - xj)
+                ip := ip + (yi/xp) * pp
+            ip
+
+@
+<<PINTERPA.dotabb>>=
+"PINTERPA" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PINTERPA"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PINTERPA" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PNTHEORY PolynomialNumberTheoryFunctions}
 \pagehead{PolynomialNumberTheoryFunctions}{PNTHEORY}
 \pagepic{ps/v104polynomialnumbertheoryfunctions.ps}{PNTHEORY}{1.00}
@@ -58027,6 +63984,193 @@ PolynomialRoots(E, V, R, P, F):Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PSQFR PolynomialSquareFree}
+\pagehead{PolynomialSquareFree}{PSQFR}
+\pagepic{ps/v104polynomialsquarefree.ps}{PSQFR}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PSQFR PolynomialSquareFree>>=
+)abbrev package PSQFR PolynomialSquareFree
+++ Author:
+++ Date Created:
+++ Date Last Updated: November 1993, (P.Gianni)
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package computes square-free decomposition of multivariate
+++ polynomials over a coefficient ring which is an arbitrary gcd domain.
+++ The requirement on the coefficient domain guarantees that the \spadfun{content} can be
+++ removed so that factors will be primitive as well as square-free.
+++ Over an infinite ring of finite characteristic,it may not be possible to
+++ guarantee that the factors are square-free.
+
+PolynomialSquareFree(VarSet:OrderedSet,E,RC:GcdDomain,P):C == T where
+  E:OrderedAbelianMonoidSup
+  P:PolynomialCategory(RC,E,VarSet)
+
+  C == with
+    squareFree : P -> Factored P
+      ++ squareFree(p) returns the square-free factorization of the
+      ++ polynomial p.  Each factor has no repeated roots, and the
+      ++ factors are pairwise relatively prime.
+
+  T == add
+    SUP    ==> SparseUnivariatePolynomial(P)
+    NNI    ==> NonNegativeInteger
+    fUnion ==> Union("nil", "sqfr", "irred", "prime")
+    FF     ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
+
+    finSqFr : (P,List VarSet) -> Factored P
+    pthPower : P -> Factored P
+    pPolRoot : P -> P
+    putPth   : P -> P
+
+    chrc:=characteristic$RC
+
+    if RC has CharacteristicNonZero then
+    -- find the p-th root of a polynomial
+      pPolRoot(f:P) : P ==
+        lvar:=variables f
+        empty? lvar => f
+        mv:=first lvar
+        uf:=univariate(f,mv)
+        uf:=divideExponents(uf,chrc)::SUP
+        uf:=map(pPolRoot,uf)
+        multivariate(uf,mv)
+
+    -- substitute variables with their p-th power
+      putPth(f:P) : P ==
+        lvar:=variables f
+        empty? lvar => f
+        mv:=first lvar
+        uf:=univariate(f,mv)
+        uf:=multiplyExponents(uf,chrc)::SUP
+        uf:=map(putPth,uf)
+        multivariate(uf,mv)
+
+    -- the polynomial is a perfect power
+      pthPower(f:P) : Factored P ==
+        proot : P := 0
+        isSq  : Boolean := false
+        if (g:=charthRoot f) case "failed" then proot:=pPolRoot(f)
+        else
+          proot := g :: P
+          isSq  := true
+        psqfr:=finSqFr(proot,variables f)
+        isSq  =>
+          makeFR((unit psqfr)**chrc,[[u.flg,u.fctr,
+           (u.xpnt)*chrc] for u in factorList psqfr])
+        makeFR((unit psqfr),[["nil",putPth u.fctr,u.xpnt]
+                             for u in factorList psqfr])
+
+    -- compute the square free decomposition, finite characteristic case
+      finSqFr(f:P,lvar:List VarSet) : Factored P ==
+         empty? lvar => pthPower(f)
+         mv:=first lvar
+         lvar:=lvar.rest
+         differentiate(f,mv)=0 => finSqFr(f,lvar)
+         uf:=univariate(f,mv)
+         cont := content uf
+         cont1:P:=1
+         uf := (uf exquo cont)::SUP
+         squf := squareFree(uf)$UnivariatePolynomialSquareFree(P,SUP)
+         pfaclist:List FF :=[]
+         for u in factorList squf repeat
+           uexp:NNI:=(u.xpnt):NNI
+           u.flg = "sqfr" =>  -- the square free factor is OK
+             pfaclist:= cons([u.flg,multivariate(u.fctr,mv),uexp],
+                              pfaclist)
+           --listfin1:= finSqFr(multivariate(u.fctr,mv),lvar)
+           listfin1:= squareFree multivariate(u.fctr,mv)
+           flistfin1:=[[uu.flg,uu.fctr,uu.xpnt*uexp]
+                        for uu in factorList listfin1]
+           cont1:=cont1*((unit listfin1)**uexp)
+           pfaclist:=append(flistfin1,pfaclist)
+         cont:=cont*cont1
+         cont ^= 1 =>
+           sqp := squareFree cont
+           pfaclist:= append (factorList sqp,pfaclist)
+           makeFR(unit(sqp)*coefficient(unit squf,0),pfaclist)
+         makeFR(coefficient(unit squf,0),pfaclist)
+
+    squareFree(p:P) ==
+       mv:=mainVariable p
+       mv case "failed" => makeFR(p,[])$Factored(P)
+       characteristic$RC ^=0 => finSqFr(p,variables p)
+       up:=univariate(p,mv)
+       cont := content up
+       up := (up exquo cont)::SUP
+       squp := squareFree(up)$UnivariatePolynomialSquareFree(P,SUP)
+       pfaclist:List FF :=
+         [[u.flg,multivariate(u.fctr,mv),u.xpnt]
+                                            for u in factorList squp]
+       cont ^= 1 =>
+         sqp := squareFree cont
+         makeFR(unit(sqp)*coefficient(unit squp,0),
+              append(factorList sqp, pfaclist))
+       makeFR(coefficient(unit squp,0),pfaclist)
+
+@
+<<PSQFR.dotabb>>=
+"PSQFR" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PSQFR"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PSQFR" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package POLY2UP PolynomialToUnivariatePolynomial}
+\pagehead{PolynomialToUnivariatePolynomial}{POLY2UP}
+\pagepic{ps/v104polynomialtounivariatepolynomial.ps}{POLY2UP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package POLY2UP PolynomialToUnivariatePolynomial>>=
+)abbrev package POLY2UP PolynomialToUnivariatePolynomial
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package is primarily to help the interpreter do coercions.
+++ It allows you to view a polynomial as a
+++ univariate polynomial in one of its variables with
+++ coefficients which are again a polynomial in all the
+++ other variables.
+
+PolynomialToUnivariatePolynomial(x:Symbol, R:Ring): with
+  univariate: (Polynomial R, Variable x) ->
+                                   UnivariatePolynomial(x, Polynomial R)
+     ++ univariate(p, x) converts the polynomial p to a one of type
+     ++ \spad{UnivariatePolynomial(x,Polynomial(R))}, ie. as a member of \spad{R[...][x]}.
+ == add
+  univariate(p, y) ==
+    q:SparseUnivariatePolynomial(Polynomial R) := univariate(p, x)
+    map(#1, q)$UnivariatePolynomialCategoryFunctions2(Polynomial R,
+                  SparseUnivariatePolynomial Polynomial R, Polynomial R,
+                      UnivariatePolynomial(x, Polynomial R))
+
+@
+<<POLY2UP.dotabb>>=
+"POLY2UP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=POLY2UP"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"POLY2UP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package LIMITPS PowerSeriesLimitPackage}
 \pagehead{PowerSeriesLimitPackage}{LIMITPS}
 \pagepic{ps/v104powerserieslimitpackage.ps}{LIMITPS}{1.00}
@@ -58739,6 +64883,126 @@ PrimitiveArrayFunctions2(A, B): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PRIMELT PrimitiveElement}
+\pagehead{PrimitiveElement}{PRIMELT}
+\pagepic{ps/v104primitiveelement.ps}{PRIMELT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PRIMELT PrimitiveElement>>=
+)abbrev package PRIMELT PrimitiveElement
+++ Computation of primitive elements.
+++ Author: Manuel Bronstein
+++ Date Created: 6 Jun 1990
+++ Date Last Updated: 25 April 1991
+++ Description:
+++   PrimitiveElement provides functions to compute primitive elements
+++   in algebraic extensions;
+++ Keywords: algebraic, extension, primitive.
+PrimitiveElement(F): Exports == Implementation where
+  F : Join(Field, CharacteristicZero)
+
+  SY  ==> Symbol
+  P   ==> Polynomial F
+  UP  ==> SparseUnivariatePolynomial F
+  RC  ==> Record(coef1: Integer, coef2: Integer, prim:UP)
+  REC ==> Record(coef: List Integer, poly:List UP, prim: UP)
+
+  Exports ==> with
+    primitiveElement: (P, SY, P, SY) -> RC
+      ++ primitiveElement(p1, a1, p2, a2) returns \spad{[c1, c2, q]}
+      ++ such that \spad{k(a1, a2) = k(a)}
+      ++ where \spad{a = c1 a1 + c2 a2, and q(a) = 0}.
+      ++ The pi's are the defining polynomials for the ai's.
+      ++ The p2 may involve a1, but p1 must not involve a2.
+      ++ This operation uses \spadfun{resultant}.
+    primitiveElement: (List P, List SY) -> REC
+      ++ primitiveElement([p1,...,pn], [a1,...,an]) returns
+      ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
+      ++ such that then \spad{k(a1,...,an) = k(a)},
+      ++ where \spad{a = a1 c1 + ... + an cn},
+      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+      ++ The pi's are the defining polynomials for the ai's.
+      ++ This operation uses the technique of
+      ++ \spadglossSee{groebner bases}{Groebner basis}.
+    primitiveElement: (List P, List SY, SY) -> REC
+      ++ primitiveElement([p1,...,pn], [a1,...,an], a) returns
+      ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
+      ++ such that then \spad{k(a1,...,an) = k(a)},
+      ++ where \spad{a = a1 c1 + ... + an cn},
+      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+      ++ The pi's are the defining polynomials for the ai's.
+      ++ This operation uses the technique of
+      ++ \spadglossSee{groebner bases}{Groebner basis}.
+
+  Implementation ==> add
+    import PolyGroebner(F)
+
+    multi     : (UP, SY) -> P
+    randomInts: (NonNegativeInteger, NonNegativeInteger) -> List Integer
+    findUniv  : (List P, SY, SY) -> Union(P, "failed")
+    incl?     : (List SY, List SY) -> Boolean
+    triangularLinearIfCan:(List P,List SY,SY) -> Union(List UP,"failed")
+    innerPrimitiveElement: (List P, List SY, SY) -> REC
+
+    multi(p, v)            == multivariate(map(#1, p), v)
+    randomInts(n, m)       == [symmetricRemainder(random()$Integer, m) for i in 1..n]
+    incl?(a, b)            == every?(member?(#1, b), a)
+    primitiveElement(l, v) == primitiveElement(l, v, new()$SY)
+
+    primitiveElement(p1, a1, p2, a2) ==
+--      one? degree(p2, a1) => [0, 1, univariate resultant(p1, p2, a1)]
+      (degree(p2, a1) = 1) => [0, 1, univariate resultant(p1, p2, a1)]
+      u := (new()$SY)::P
+      b := a2::P
+      for i in 10.. repeat
+        c := symmetricRemainder(random()$Integer, i)
+        w := u - c * b
+        r := univariate resultant(eval(p1, a1, w), eval(p2, a1, w), a2)
+        not zero? r and r = squareFreePart r => return [1, c, r]
+
+    findUniv(l, v, opt) ==
+      for p in l repeat
+        degree(p, v) > 0 and incl?(variables p, [v, opt]) => return p
+      "failed"
+
+    triangularLinearIfCan(l, lv, w) ==
+      (u := findUniv(l, w, w)) case "failed" => "failed"
+      pw := univariate(u::P)
+      ll := nil()$List(UP)
+      for v in lv repeat
+        ((u := findUniv(l, v, w)) case "failed") or
+          (degree(p := univariate(u::P, v)) ^= 1) => return "failed"
+        (bc := extendedEuclidean(univariate leadingCoefficient p, pw,1))
+           case "failed" => error "Should not happen"
+        ll := concat(map(#1,
+                (- univariate(coefficient(p,0)) * bc.coef1) rem pw), ll)
+      concat(map(#1, pw), reverse_! ll)
+
+    primitiveElement(l, vars, uu) ==
+      u    := uu::P
+      vv   := [v::P for v in vars]
+      elim := concat(vars, uu)
+      w    := uu::P
+      n    := #l
+      for i in 10.. repeat
+        cf := randomInts(n, i)
+        (tt := triangularLinearIfCan(lexGroebner(
+             concat(w - +/[c * t for c in cf for t in vv], l), elim),
+                vars, uu)) case List(UP) =>
+                   ltt := tt::List(UP)
+                   return([cf, rest ltt, first ltt])
+
+@
+<<PRIMELT.dotabb>>=
+"PRIMELT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PRIMELT"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"PRIMELT" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ODEPRIM PrimitiveRatDE}
 \pagehead{PrimitiveRatDE}{ODEPRIM}
 \pagepic{ps/v104primitiveratde.ps}{ODEPRIM}{1.00}
@@ -58931,6 +65195,1155 @@ PrimitiveRatDE(F, UP, L, LQ): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PRINT PrintPackage}
+\pagehead{PrintPackage}{PRINT}
+\pagepic{ps/v104printpackage.ps}{PRINT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PRINT PrintPackage>>=
+)abbrev package PRINT PrintPackage
+++ Author: Scott Morrison
+++ Date Created: Aug. 1, 1990
+++ Date Last Updated: 
+++ Basic Operations: print
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: print
+++ References:
+++ Description: PrintPackage provides a print function for output forms.
+PrintPackage(): with
+    print : OutputForm ->  Void
+      ++ print(o) writes the output form o on standard output using the
+      ++ two-dimensional formatter.
+ == add
+    print(x) == print(x)$OutputForm
+
+@
+<<PRINT.dotabb>>=
+"PRINT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PRINT"]
+"Package" [color="#FF4488"]
+"PRINT" -> "Package"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PSEUDLIN PseudoLinearNormalForm}
+\pagehead{PseudoLinearNormalForm}{PSEUDLIN}
+\pagepic{ps/v104pseudolinearnormalform.ps}{PSEUDLIN}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PSEUDLIN PseudoLinearNormalForm>>=
+)abbrev package PSEUDLIN PseudoLinearNormalForm
+++ Normal forms of pseudo-linear operators
+++ Author: Bruno Zuercher
+++ Date Created: November 1993
+++ Date Last Updated: 12 April 1994
+++ Description:
+++   PseudoLinearNormalForm provides a function for computing a block-companion
+++   form for pseudo-linear operators.
+PseudoLinearNormalForm(K:Field): Exports == Implementation where
+  ER  ==> Record(C: Matrix K, g: Vector K)
+  REC ==> Record(R: Matrix K, A: Matrix K, Ainv: Matrix K)
+
+  Exports ==> with
+    normalForm: (Matrix K, Automorphism K, K -> K) -> REC
+      ++ normalForm(M, sig, der) returns \spad{[R, A, A^{-1}]} such that
+      ++ the pseudo-linear operator whose matrix in the basis \spad{y} is
+      ++ \spad{M} had matrix \spad{R} in the basis \spad{z = A y}.
+      ++ \spad{der} is a \spad{sig}-derivation.
+    changeBase: (Matrix K, Matrix K, Automorphism K, K -> K) -> Matrix K
+      ++ changeBase(M, A, sig, der): computes the new matrix of a pseudo-linear
+      ++ transform given by the matrix M under the change of base A
+    companionBlocks: (Matrix K, Vector K) -> List ER
+      ++ companionBlocks(m, v) returns \spad{[[C_1, g_1],...,[C_k, g_k]]}
+      ++ such that each \spad{C_i} is a companion block and
+      ++ \spad{m = diagonal(C_1,...,C_k)}.
+
+  Implementation ==> add
+    normalForm0: (Matrix K, Automorphism K, Automorphism K, K -> K) -> REC
+    mulMatrix: (Integer, Integer, K) -> Matrix K
+      -- mulMatrix(N, i, a): under a change of base with the resulting matrix of
+      -- size N*N the following operations are performed:
+      -- D1: column i will be multiplied by sig(a)
+      -- D2: row i will be multiplied by 1/a
+      -- D3: addition of der(a)/a to the element at position (i,i)
+    addMatrix: (Integer, Integer, Integer, K) -> Matrix K
+      -- addMatrix(N, i, k, a): under a change of base with the resulting matrix
+      -- of size N*N the following operations are performed:
+      -- C1: addition of column i multiplied by sig(a) to column k
+      -- C2: addition of row k multiplied by -a to row i
+      -- C3: addition of -a*der(a) to the element at position (i,k)
+    permutationMatrix: (Integer, Integer, Integer) -> Matrix K
+      -- permutationMatrix(N, i, k): under a change of base with the resulting
+      -- permutation matrix of size N*N the following operations are performed:
+      -- P1: columns i and k will be exchanged
+      -- P2: rows i and k will be exchanged
+    inv: Matrix K -> Matrix K
+      -- inv(M): computes the inverse of a invertable matrix M.
+      -- avoids possible type conflicts
+
+    inv m                      == inverse(m) :: Matrix K
+    changeBase(M, A, sig, der) == inv(A) * (M * map(sig #1, A) + map(der, A))
+    normalForm(M, sig, der)    == normalForm0(M, sig, inv sig, der)
+
+    companionBlocks(R, w) ==
+      -- decomposes the rational matrix R into single companion blocks
+      -- and the inhomogenity w as well
+      i:Integer := 1
+      n := nrows R
+      l:List(ER) := empty()
+      while i <= n repeat
+        j := i
+        while j+1 <= n and R(j,j+1) = 1 repeat j := j+1
+        --split block now
+        v:Vector K := new((j-i+1)::NonNegativeInteger, 0)
+        for k in i..j repeat v(k-i+1) := w k
+        l := concat([subMatrix(R,i,j,i,j), v], l)
+        i := j+1
+      l
+
+    normalForm0(M, sig, siginv, der) ==
+      -- the changes of base will be incremented in B and Binv,
+      -- where B**(-1)=Binv; E defines an elementary matrix
+      B, Binv, E    : Matrix K
+      recOfMatrices : REC
+      N := nrows M
+      B := diagonalMatrix [1 for k in 1..N]
+      Binv := copy B
+      -- avoid unnecessary recursion
+      if diagonal?(M) then return [M, B, Binv]
+      i : Integer := 1
+      while i < N repeat
+        j := i + 1
+        while j <= N and M(i, j) = 0 repeat  j := j + 1
+        if j <= N then
+          -- expand companionblock by lemma 5
+          if j ^= i+1 then
+            -- perform first a permutation
+            E := permutationMatrix(N, i+1, j)
+            M := changeBase(M, E, sig, der)
+            B := B*E
+            Binv := E*Binv
+          -- now is M(i, i+1) ^= 0
+          E := mulMatrix(N, i+1, siginv inv M(i,i+1))
+          M := changeBase(M, E, sig, der)
+          B := B*E
+          Binv := inv(E)*Binv
+          for j in 1..N repeat
+            if j ^= i+1 then
+              E := addMatrix(N, i+1, j, siginv(-M(i,j)))
+              M := changeBase(M, E, sig, der)
+              B := B*E
+              Binv := inv(E)*Binv
+          i := i + 1
+        else
+          -- apply lemma 6
+          for j in i..2 by -1 repeat
+            for k in (i+1)..N repeat
+              E := addMatrix(N, k, j-1, M(k,j))
+              M := changeBase(M, E, sig, der)
+              B := B*E
+              Binv := inv(E)*Binv
+          j := i + 1
+          while j <= N and M(j,1) = 0 repeat  j := j + 1
+          if j <= N then
+            -- expand companionblock by lemma 8
+            E := permutationMatrix(N, 1, j)
+            M := changeBase(M, E, sig, der)
+            B := B*E
+            Binv := E*Binv
+            -- start again to establish rational form
+            i := 1
+          else
+            -- split a direct factor
+            recOfMatrices :=
+              normalForm(subMatrix(M, i+1, N, i+1, N), sig, der)
+            setsubMatrix!(M, i+1, i+1, recOfMatrices.R)
+            E := diagonalMatrix [1 for k in 1..N]
+            setsubMatrix!(E, i+1, i+1, recOfMatrices.A)
+            B := B*E
+            setsubMatrix!(E, i+1, i+1, recOfMatrices.Ainv)
+            Binv := E*Binv
+            -- M in blockdiagonalform, stop program
+            i := N
+      [M, B, Binv]
+
+    mulMatrix(N, i, a) ==
+      M : Matrix K := diagonalMatrix [1 for j in 1..N]
+      M(i, i) := a
+      M
+
+    addMatrix(N, i, k, a) ==
+      A : Matrix K := diagonalMatrix [1 for j in 1..N]
+      A(i, k) := a
+      A
+
+    permutationMatrix(N, i, k) ==
+      P : Matrix K := diagonalMatrix [1 for j in 1..N]
+      P(i, i) := P(k, k) := 0
+      P(i, k) := P(k, i) := 1
+      P
+
+@
+<<PSEUDLIN.dotabb>>=
+"PSEUDLIN" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PSEUDLIN"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"PSEUDLIN" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package PRS PseudoRemainderSequence}
+The package constructor {\bf PseudoRemainderSequence} provides
+efficient algorithms by Lionel Ducos (University of Poitiers, France)
+for computing sub-resultants. This leads to a speed up in many places
+in Axiom where sub-resultants are computed (polynomial system solving,
+algebraic factorization, integration).
+\pagehead{PseudoRemainderSequence}{PRS}
+\pagepic{ps/v104pseudoremaindersequence.ps}{PRS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package PRS PseudoRemainderSequence>>=
+)abbrev package PRS PseudoRemainderSequence
+++ Author: Ducos Lionel
+++ Date Created: january 1995
+++ Date Last Updated: 5 february 1999
+++ Basic Functions: 
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description: This package contains some functions:
+++ \axiomOpFrom{discriminant}{PseudoRemainderSequence}, 
+++ \axiomOpFrom{resultant}{PseudoRemainderSequence}, 
+++ \axiomOpFrom{subResultantGcd}{PseudoRemainderSequence},
+++ \axiomOpFrom{chainSubResultants}{PseudoRemainderSequence}, 
+++ \axiomOpFrom{degreeSubResultant}{PseudoRemainderSequence}, 
+++ \axiomOpFrom{lastSubResultant}{PseudoRemainderSequence},
+++ \axiomOpFrom{resultantEuclidean}{PseudoRemainderSequence}, 
+++ \axiomOpFrom{subResultantGcdEuclidean}{PseudoRemainderSequence},
+++ \axiomOpFrom{semiSubResultantGcdEuclidean1}{PseudoRemainderSequence},
+++ \axiomOpFrom{semiSubResultantGcdEuclidean2}{PseudoRemainderSequence}, etc.
+++ This procedures are coming from improvements 
+++ of the subresultants algorithm.
+++   Version : 7
+++   References : Lionel Ducos "Optimizations of the subresultant algorithm"
+++   to appear in the Journal of Pure and Applied Algebra.
+++   Author : Ducos Lionel \axiom{Lionel.Ducos@mathlabo.univ-poitiers.fr}
+
+PseudoRemainderSequence(R, polR) : Specification == Implementation where
+  R : IntegralDomain
+  polR : UnivariatePolynomialCategory(R)
+  NNI ==> NonNegativeInteger
+  LC  ==> leadingCoefficient
+
+  Specification == with
+       resultant : (polR, polR) -> R
+         ++ \axiom{resultant(P, Q)} returns the resultant 
+         ++ of \axiom{P} and \axiom{Q}
+
+       resultantEuclidean : (polR, polR) -> 
+                          Record(coef1 : polR, coef2 : polR, resultant : R)
+         ++ \axiom{resultantEuclidean(P,Q)} carries out the equality
+         ++ \axiom{coef1*P + coef2*Q = resultant(P,Q)}
+
+       semiResultantEuclidean2 : (polR, polR) -> 
+                          Record(coef2 : polR, resultant : R)
+         ++ \axiom{semiResultantEuclidean2(P,Q)} carries out the equality
+         ++ \axiom{...P + coef2*Q = resultant(P,Q)}.
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       semiResultantEuclidean1 : (polR, polR) -> 
+                          Record(coef1 : polR, resultant : R)
+         ++ \axiom{semiResultantEuclidean1(P,Q)} carries out the equality
+         ++ \axiom{coef1.P + ? Q = resultant(P,Q)}.
+
+       indiceSubResultant : (polR, polR, NNI) -> polR
+         ++ \axiom{indiceSubResultant(P, Q, i)} returns
+         ++ the subresultant of indice \axiom{i}
+
+       indiceSubResultantEuclidean : (polR, polR, NNI) -> 
+                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
+         ++ \axiom{indiceSubResultant(P, Q, i)} returns
+         ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
+         ++ \axiom{coef1*P + coef2*Q = S_i(P,Q)}
+
+       semiIndiceSubResultantEuclidean : (polR, polR, NNI) -> 
+                          Record(coef2 : polR, subResultant : polR)
+         ++ \axiom{semiIndiceSubResultantEuclidean(P, Q, i)} returns
+         ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
+         ++ \axiom{...P + coef2*Q = S_i(P,Q)}
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       degreeSubResultant : (polR, polR, NNI) -> polR
+         ++ \axiom{degreeSubResultant(P, Q, d)} computes 
+         ++ a subresultant of degree \axiom{d}.
+
+       degreeSubResultantEuclidean : (polR, polR, NNI) -> 
+                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
+         ++ \axiom{indiceSubResultant(P, Q, i)} returns
+         ++ a subresultant \axiom{S} of degree \axiom{d} 
+         ++ and carries out the equality \axiom{coef1*P + coef2*Q = S_i}.
+
+       semiDegreeSubResultantEuclidean : (polR, polR, NNI) -> 
+                          Record(coef2 : polR, subResultant : polR)
+         ++ \axiom{indiceSubResultant(P, Q, i)} returns
+         ++ a subresultant \axiom{S} of degree \axiom{d} 
+         ++ and carries out the equality \axiom{...P + coef2*Q = S_i}.
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       lastSubResultant : (polR, polR) -> polR
+         ++ \axiom{lastSubResultant(P, Q)} computes 
+         ++ the last non zero subresultant of \axiom{P} and \axiom{Q}
+
+       lastSubResultantEuclidean : (polR, polR) -> 
+                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
+         ++ \axiom{lastSubResultantEuclidean(P, Q)} computes
+         ++ the last non zero subresultant \axiom{S} 
+         ++ and carries out the equality \axiom{coef1*P + coef2*Q = S}.
+
+       semiLastSubResultantEuclidean : (polR, polR) -> 
+                       Record(coef2 : polR, subResultant : polR)
+         ++ \axiom{semiLastSubResultantEuclidean(P, Q)} computes
+         ++ the last non zero subresultant \axiom{S} 
+         ++ and carries out the equality \axiom{...P + coef2*Q = S}.
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       subResultantGcd : (polR, polR) -> polR
+         ++ \axiom{subResultantGcd(P, Q)} returns the gcd 
+         ++ of two primitive polynomials \axiom{P} and \axiom{Q}.
+
+       subResultantGcdEuclidean : (polR, polR) 
+                     -> Record(coef1 : polR, coef2 : polR, gcd : polR)
+         ++ \axiom{subResultantGcdEuclidean(P,Q)} carries out the equality
+         ++ \axiom{coef1*P + coef2*Q = +/- S_i(P,Q)}
+         ++ where the degree (not the indice) 
+         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+
+       semiSubResultantGcdEuclidean2 : (polR, polR) 
+                                   -> Record(coef2 : polR, gcd : polR)
+         ++ \axiom{semiSubResultantGcdEuclidean2(P,Q)} carries out the equality
+         ++ \axiom{...P + coef2*Q = +/- S_i(P,Q)}
+         ++ where the degree (not the indice) 
+         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       semiSubResultantGcdEuclidean1: (polR, polR)->Record(coef1: polR, gcd: polR)
+         ++ \axiom{semiSubResultantGcdEuclidean1(P,Q)} carries out the equality
+         ++ \axiom{coef1*P + ? Q = +/- S_i(P,Q)}
+         ++ where the degree (not the indice) 
+         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+
+       discriminant : polR -> R
+         ++ \axiom{discriminant(P, Q)} returns the discriminant 
+         ++ of \axiom{P} and \axiom{Q}.
+
+       discriminantEuclidean : polR -> 
+                           Record(coef1 : polR, coef2 : polR, discriminant : R)
+         ++ \axiom{discriminantEuclidean(P)} carries out the equality
+         ++ \axiom{coef1 * P + coef2 * D(P) = discriminant(P)}.
+
+       semiDiscriminantEuclidean : polR -> 
+                           Record(coef2 : polR, discriminant : R)
+         ++ \axiom{discriminantEuclidean(P)} carries out the equality
+         ++ \axiom{...P + coef2 * D(P) = discriminant(P)}.
+         ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+       chainSubResultants : (polR, polR) -> List(polR)
+         ++ \axiom{chainSubResultants(P, Q)} computes the list
+         ++ of non zero subresultants of \axiom{P} and \axiom{Q}.
+
+       schema : (polR, polR) -> List(NNI)
+         ++ \axiom{schema(P,Q)} returns the list of degrees of
+         ++ non zero subresultants of \axiom{P} and \axiom{Q}.
+
+       if R has GcdDomain then
+         resultantReduit : (polR, polR) -> R 
+         ++ \axiom{resultantReduit(P,Q)} returns the "reduce resultant"
+         ++ of \axiom{P} and \axiom{Q}.
+
+         resultantReduitEuclidean : (polR, polR) -> 
+                        Record(coef1 : polR, coef2 : polR, resultantReduit : R)
+         ++ \axiom{resultantReduitEuclidean(P,Q)} returns 
+         ++ the "reduce resultant" and carries out the equality
+         ++ \axiom{coef1*P + coef2*Q = resultantReduit(P,Q)}.
+
+         semiResultantReduitEuclidean : (polR, polR) -> 
+                        Record(coef2 : polR, resultantReduit : R)
+         ++ \axiom{semiResultantReduitEuclidean(P,Q)} returns 
+         ++ the "reduce resultant" and carries out the equality
+         ++ \axiom{...P + coef2*Q = resultantReduit(P,Q)}.
+
+         gcd : (polR, polR) -> polR 
+         ++ \axiom{gcd(P, Q)} returns the gcd of \axiom{P} and \axiom{Q}.
+       
+       -- sub-routines exported for convenience ----------------------------
+
+       "*" : (R, Vector(polR)) -> Vector(polR)
+         ++ \axiom{r * v} computes the product of \axiom{r} and \axiom{v}
+
+       "exquo" : (Vector(polR), R) -> Vector(polR)
+         ++ \axiom{v exquo r} computes 
+         ++ the exact quotient of \axiom{v} by \axiom{r}
+         
+       pseudoDivide : (polR, polR) -> 
+                                Record(coef:R, quotient:polR, remainder:polR)
+         ++ \axiom{pseudoDivide(P,Q)} computes the pseudoDivide 
+         ++ of \axiom{P} by \axiom{Q}.
+
+       divide : (polR, polR) -> Record(quotient : polR, remainder : polR)
+         ++ \axiom{divide(F,G)} computes quotient and rest 
+         ++ of the exact euclidean division of \axiom{F} by \axiom{G}.
+
+       Lazard : (R, R, NNI) -> R
+         ++ \axiom{Lazard(x, y, n)} computes \axiom{x**n/y**(n-1)}
+       
+       Lazard2 : (polR, R, R, NNI) -> polR
+         ++ \axiom{Lazard2(F, x, y, n)} computes  \axiom{(x/y)**(n-1) * F}
+         
+       next_sousResultant2 : (polR, polR, polR, R) -> polR
+         ++ \axiom{nextsousResultant2(P, Q, Z, s)} returns
+         ++ the subresultant \axiom{S_{e-1}} where
+         ++ \axiom{P ~ S_d,  Q = S_{d-1},  Z = S_e,  s = lc(S_d)}
+
+       resultant_naif : (polR, polR) -> R
+         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
+         ++ the resultant of \axiom{P} and \axiom{Q} computed 
+         ++ by means of the naive algorithm.
+
+       resultantEuclidean_naif : (polR, polR) -> 
+                          Record(coef1 : polR, coef2 : polR, resultant : R)
+         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
+         ++ the extended resultant of \axiom{P} and \axiom{Q} computed 
+         ++ by means of the naive algorithm.
+
+       semiResultantEuclidean_naif : (polR, polR) -> 
+                          Record(coef2 : polR, resultant : R)
+         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
+         ++ the semi-extended resultant of \axiom{P} and \axiom{Q} computed 
+         ++ by means of the naive algorithm.
+
+  Implementation == add
+    X : polR := monomial(1$R,1)
+
+    r : R * v : Vector(polR) == r::polR * v
+              -- the instruction  map(r * #1, v) is slower !?
+
+    v : Vector(polR) exquo r : R == map((#1 exquo r)::polR, v)
+
+    pseudoDivide(P : polR, Q : polR) : 
+                                 Record(coef:R,quotient:polR,remainder:polR) ==
+    -- computes the pseudoDivide of P by Q
+       zero?(Q) => error("PseudoDivide$PRS : division by 0")
+       zero?(P) => construct(1, 0, P)
+       lcQ : R := LC(Q)
+       (degP, degQ) := (degree(P), degree(Q))
+       degP < degQ => construct(1, 0, P)
+       Q := reductum(Q)
+       i : NNI := (degP - degQ + 1)::NNI
+       co : R := lcQ**i
+       quot : polR := 0$polR
+       while (delta : Integer := degree(P) - degQ) >= 0 repeat
+         i := (i - 1)::NNI
+         mon := monomial(LC(P), delta::NNI)$polR
+         quot := quot + lcQ**i * mon
+         P := lcQ * reductum(P) - mon * Q
+       P := lcQ**i * P
+       return construct(co, quot, P)
+
+    divide(F : polR, G : polR) : Record(quotient : polR, remainder : polR)==
+    -- computes quotient and rest of the exact euclidean division of F by G
+         lcG : R := LC(G)
+         degG : NNI := degree(G)
+         zero?(degG) => ( F := (F exquo lcG)::polR; return construct(F, 0))
+         G : polR := reductum(G)
+         quot : polR := 0
+         while (delta := degree(F) - degG) >= 0 repeat
+            mon : polR := monomial((LC(F) exquo lcG)::R, delta::NNI)
+            quot := quot + mon
+            F := reductum(F) - mon * G
+         return construct(quot, F)
+
+    resultant_naif(P : polR, Q : polR) : R ==
+    -- valid over a field
+       a : R := 1
+       repeat
+          zero?(Q) => return 0
+          (degP, degQ) := (degree(P), degree(Q))
+          if odd?(degP) and odd?(degQ) then a := - a
+          zero?(degQ) => return (a * LC(Q)**degP)
+          U : polR := divide(P, Q).remainder
+          a := a * LC(Q)**(degP - degree(U))::NNI
+          (P, Q) := (Q, U)
+
+    resultantEuclidean_naif(P : polR, Q : polR) :
+                       Record(coef1 : polR, coef2 : polR, resultant : R) ==
+    -- valid over a field.
+       a : R := 1
+       old_cf1 : polR := 1 ; cf1 : polR := 0
+       old_cf2 : polR := 0 ; cf2 : polR := 1
+       repeat
+          zero?(Q) => construct(0::polR, 0::polR, 0::R)
+          (degP, degQ) := (degree(P), degree(Q))
+          if odd?(degP) and odd?(degQ) then a := -a
+          if zero?(degQ) then
+             a := a * LC(Q)**(degP-1)::NNI
+             return construct(a*cf1, a*cf2, a*LC(Q))
+          divid := divide(P,Q)
+          a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
+          (P, Q) := (Q, divid.remainder)
+          (old_cf1, old_cf2, cf1, cf2) := (cf1, cf2, 
+                old_cf1 - divid.quotient * cf1, old_cf2 - divid.quotient * cf2)
+
+    semiResultantEuclidean_naif(P : polR, Q : polR) :
+                       Record(coef2 : polR, resultant : R) ==
+    -- valid over a field
+       a : R := 1
+       old_cf2 : polR := 0 ; cf2 : polR := 1
+       repeat
+          zero?(Q) => construct(0::polR, 0::R)
+          (degP, degQ) := (degree(P), degree(Q))
+          if odd?(degP) and odd?(degQ) then a := -a
+          if zero?(degQ) then
+             a := a * LC(Q)**(degP-1)::NNI
+             return construct(a*cf2, a*LC(Q))
+          divid := divide(P,Q)
+          a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
+          (P, Q) := (Q, divid.remainder)
+          (old_cf2, cf2) := (cf2, old_cf2 - divid.quotient * cf2)
+
+    Lazard(x : R, y : R, n : NNI) : R ==
+       zero?(n) => error("Lazard$PRS : n = 0")
+--       one?(n) => x
+       (n = 1) => x
+       a : NNI := 1
+       while n >= (b := 2*a) repeat a := b
+       c : R := x
+       n := (n - a)::NNI
+       repeat                    --  c = x**i / y**(i-1),  i=n_0 quo a,  a=2**?
+--          one?(a) => return c
+          (a = 1) => return c
+          a := a quo 2
+          c := ((c * c) exquo y)::R
+          if n >= a then ( c := ((c * x) exquo y)::R ; n := (n - a)::NNI )
+
+    Lazard2(F : polR, x : R, y : R, n : NNI) : polR ==
+       zero?(n) => error("Lazard2$PRS : n = 0")
+--       one?(n) => F
+       (n = 1) => F
+       x := Lazard(x, y, (n-1)::NNI)
+       return ((x * F) exquo y)::polR
+
+    Lazard3(V : Vector(polR), x : R, y : R, n : NNI) : Vector(polR) ==
+    -- computes x**(n-1) * V / y**(n-1)
+       zero?(n) => error("Lazard2$prs : n = 0")
+--       one?(n) => V
+       (n = 1) => V
+       x := Lazard(x, y, (n-1)::NNI)
+       return ((x * V) exquo y)
+
+    next_sousResultant2(P : polR, Q : polR, Z : polR, s : R) : polR ==
+       (lcP, c, se) := (LC(P), LC(Q), LC(Z))
+       (d, e) := (degree(P), degree(Q))
+       (P, Q, H) := (reductum(P), reductum(Q), - reductum(Z))
+       A : polR := coefficient(P, e) * H
+       for i in e+1..d-1 repeat 
+          H := if degree(H) = e-1 then  
+                  X * reductum(H) - ((LC(H) * Q) exquo c)::polR
+               else
+                  X * H
+          -- H = s_e * X^i mod S_d-1
+          A := coefficient(P, i) * H + A
+       while degree(P) >= e repeat P := reductum(P)
+       A := A + se * P            --  A = s_e * reductum(P_0)       mod S_d-1
+       A := (A exquo lcP)::polR   --  A = s_e * reductum(S_d) / s_d mod S_d-1
+       A := if degree(H) = e-1 then 
+               c * (X * reductum(H) + A) - LC(H) * Q
+            else
+               c * (X * H + A)
+       A := (A exquo s)::polR                    -- A = +/- S_e-1
+       return (if odd?(d-e) then A else - A)
+
+    next_sousResultant3(VP : Vector(polR), VQ : Vector(polR), s : R, ss : R) :
+                                                      Vector(polR) ==
+    -- P ~ S_d,  Q = S_d-1,  s = lc(S_d),  ss = lc(S_e)
+       (P, Q) := (VP.1, VQ.1)
+       (lcP, c) := (LC(P), LC(Q))
+       e : NNI := degree(Q)
+--       if one?(delta := degree(P) - e) then                   -- algo_new
+       if ((delta := degree(P) - e) = 1) then                   -- algo_new
+         VP := c * VP - coefficient(P, e) * VQ
+         VP := VP exquo lcP
+         VP := c * (VP - X * VQ) + coefficient(Q, (e-1)::NNI) * VQ
+         VP := VP exquo s
+       else                                    -- algorithm of Lickteig - Roy
+         (r, rr) := (s * lcP, ss * c)
+         divid := divide(rr * P, Q)
+         VP.1 := (divid.remainder exquo r)::polR
+         for i in 2..#VP repeat
+           VP.i := rr * VP.i - VQ.i * divid.quotient
+           VP.i := (VP.i exquo r)::polR
+       return (if odd?(delta) then VP else - VP)
+
+    algo_new(P : polR, Q : polR) : R ==
+       delta : NNI := (degree(P) - degree(Q))::NNI
+       s : R := LC(Q)**delta
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       repeat      
+          -- P = S_c-1 (except the first turn : P ~ S_c-1), 
+          -- Q = S_d-1,  s = lc(S_d)
+          zero?(Q) => return 0
+          delta := (degree(P) - degree(Q))::NNI
+          Z : polR := Lazard2(Q, LC(Q), s, delta)          
+          -- Z = S_e ~ S_d-1
+          zero?(degree(Z)) => return LC(Z)
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    resultant(P : polR, Q : polR) : R ==
+       zero?(Q) or zero?(P) => 0
+       if degree(P) < degree(Q) then 
+          (P, Q) := (Q, P)
+          if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
+       zero?(degree(Q)) => LC(Q)**degree(P)
+       -- degree(P) >= degree(Q) > 0
+       R has Finite => resultant_naif(P, Q)
+       return algo_new(P, Q)
+
+    subResultantEuclidean(P : polR, Q : polR) :
+                          Record(coef1 : polR, coef2 : polR, resultant : R) ==
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 0::polR, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(0::polR, 0::polR, 0::R)
+          e : NNI := degree(Q)
+          delta : NNI := (degree(P) - e)::NNI
+          if zero?(e) then
+             l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
+             return construct(l.2, l.3, LC(l.1))
+          ss : R := Lazard(LC(Q), s, delta)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    resultantEuclidean(P : polR, Q : polR) : 
+                       Record(coef1 : polR, coef2 : polR, resultant : R) ==
+       zero?(P) or zero?(Q) => construct(0::polR, 0::polR, 0::R)
+       if degree(P) < degree(Q) then 
+          e : Integer := if odd?(degree(P)) and odd?(degree(Q)) then -1 else 1
+          l := resultantEuclidean(Q, e * P)
+          return construct(e * l.coef2, l.coef1, l.resultant)
+       if zero?(degree(Q)) then
+          degP : NNI := degree(P)
+          zero?(degP) => error("resultantEuclidean$PRS : constant polynomials")
+          s : R := LC(Q)**(degP-1)::NNI
+          return construct(0::polR, s::polR, s * LC(Q))
+       R has Finite => resultantEuclidean_naif(P, Q)
+       return subResultantEuclidean(P,Q)
+
+    semiSubResultantEuclidean(P : polR, Q : polR) :
+                       Record(coef2 : polR, resultant : R) ==
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(0::polR, 0::R)
+          e : NNI := degree(Q)
+          delta : NNI := (degree(P) - e)::NNI
+          if zero?(e) then
+             l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
+             return construct(l.2, LC(l.1))
+          ss : R := Lazard(LC(Q), s, delta)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiResultantEuclidean2(P : polR, Q : polR) : 
+                       Record(coef2 : polR, resultant : R) ==
+       zero?(P) or zero?(Q) => construct(0::polR, 0::R)
+       degree(P) < degree(Q) => error("semiResultantEuclidean2 : bad degrees")
+       if zero?(degree(Q)) then
+          degP : NNI := degree(P)
+          zero?(degP) => error("semiResultantEuclidean2 : constant polynomials")
+          s : R := LC(Q)**(degP-1)::NNI
+          return construct(s::polR, s * LC(Q))
+       R has Finite => semiResultantEuclidean_naif(P, Q)
+       return semiSubResultantEuclidean(P,Q)
+
+    semiResultantEuclidean1(P : polR, Q : polR) :
+                       Record(coef1 : polR, resultant : R) ==
+       result := resultantEuclidean(P,Q)
+       [result.coef1, result.resultant]
+
+    indiceSubResultant(P : polR, Q : polR, i : NNI) : polR == 
+       zero?(Q) or zero?(P) => 0
+       if degree(P) < degree(Q) then 
+          (P, Q) := (Q, P)
+          if odd?(degree(P)-i) and odd?(degree(Q)-i) then Q := - Q
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => error("indiceSubResultant$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return s*Q
+       i > degree(Q) => 0
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       repeat
+          -- P = S_{c-1} ~ S_d , Q = S_{d-1},  s = lc(S_d),  i < d
+          (degP, degQ) := (degree(P), degree(Q))
+          i = degP-1 => return Q
+          zero?(Q) or (i > degQ) => return 0
+          Z : polR := Lazard2(Q, LC(Q), s, (degP - degQ)::NNI)
+          --  Z = S_e ~ S_d-1
+          i = degQ => return Z
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    indiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+                    Record(coef1 : polR, coef2 : polR, subResultant : polR) == 
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+       if degree(P) < degree(Q) then 
+          e := if odd?(degree(P)-i) and odd?(degree(Q)-i) then -1 else 1
+          l := indiceSubResultantEuclidean(Q, e * P, i)
+          return construct(e * l.coef2, l.coef1, l.subResultant)
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => 
+                      error("indiceSubResultantEuclidean$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return construct(0::polR, s::polR, s * Q)
+       i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 0::polR, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d),  i < d
+          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(0::polR, 0::polR, 0::polR)
+          (degP, degQ) := (degree(P), degree(Q))
+          i = degP-1 => return construct(VQ.2, VQ.3, VQ.1)
+          (i > degQ) => return construct(0::polR, 0::polR, 0::polR)
+          VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
+          i = degQ => return construct(VZ.2, VZ.3, VZ.1)
+          ss : R := LC(VZ.1)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiIndiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+                    Record(coef2 : polR, subResultant : polR) == 
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+       degree(P) < degree(Q) => 
+                  error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => 
+                  error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return construct(s::polR, s * Q)
+       i > degree(Q) => construct(0::polR, 0::polR)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d),  i < d
+          --  S_{c-1} = ...P_0 + VP.2 Q_0,  S_{d-1} = ...P_0 + ...Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(0::polR, 0::polR)
+          (degP, degQ) := (degree(P), degree(Q))
+          i = degP-1 => return construct(VQ.2, VQ.1)
+          (i > degQ) => return construct(0::polR, 0::polR)
+          VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
+          i = degQ => return construct(VZ.2, VZ.1)
+          ss : R := LC(VZ.1)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    degreeSubResultant(P : polR, Q : polR, i : NNI) : polR == 
+       zero?(Q) or zero?(P) => 0
+       if degree(P) < degree(Q) then (P, Q) := (Q, P)
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => error("degreeSubResultant$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return s*Q
+       i > degree(Q) => 0
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       repeat
+          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
+          zero?(Q) or (i > degree(Q)) => return 0
+          i = degree(Q) => return Q
+          Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
+          --  Z = S_e ~ S_d-1
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    degreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) : 
+                     Record(coef1 : polR, coef2 : polR, subResultant : polR) ==
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+       if degree(P) < degree(Q) then 
+          l := degreeSubResultantEuclidean(Q, P, i)
+          return construct(l.coef2, l.coef1, l.subResultant)
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => 
+                      error("degreeSubResultantEuclidean$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return construct(0::polR, s::polR, s * Q)
+       i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 0::polR, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) or (i > degree(Q)) => 
+               return construct(0::polR, 0::polR, 0::polR)
+          i = degree(Q) => return construct(VQ.2, VQ.3, VQ.1)
+          ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiDegreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) : 
+                     Record(coef2 : polR, subResultant : polR) ==
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+       degree(P) < degree(Q) =>
+                  error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
+       if i = degree(Q) then
+          delta : NNI := (degree(P)-degree(Q))::NNI
+          zero?(delta) => 
+                  error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
+          s : R := LC(Q)**(delta-1)::NNI
+          return construct(s::polR, s * Q)
+       i > degree(Q) => construct(0::polR, 0::polR)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) or (i > degree(Q)) => 
+               return construct(0::polR, 0::polR)
+          i = degree(Q) => return construct(VQ.2, VQ.1)
+          ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    lastSubResultant(P : polR, Q : polR) : polR ==
+       zero?(Q) or zero?(P) => 0
+       if degree(P) < degree(Q) then (P, Q) := (Q, P)
+       zero?(degree(Q)) => (LC(Q)**degree(P))::polR
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       Z : polR := P
+       repeat
+          -- Z = S_d  (except the first turn : Z = P)
+          -- P = S_{c-1} ~ S_d,  Q = S_{d-1},  s = lc(S_d)
+          zero?(Q) => return Z
+          Z := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
+          -- Z = S_e ~ S_{d-1}
+          zero?(degree(Z)) => return Z
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    lastSubResultantEuclidean(P : polR, Q : polR) :
+                    Record(coef1 : polR, coef2 : polR, subResultant : polR) == 
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+       if degree(P) < degree(Q) then 
+          l := lastSubResultantEuclidean(Q, P)
+          return construct(l.coef2, l.coef1, l.subResultant)
+       if zero?(degree(Q)) then
+          degP : NNI := degree(P)
+          zero?(degP) => 
+              error("lastSubResultantEuclidean$PRS : constant polynomials")
+          s : R := LC(Q)**(degP-1)::NNI
+          return construct(0::polR, s::polR, s * Q)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 0::polR, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+       VZ : Vector(polR) := copy(VP)
+       repeat
+          --  VZ.1 = S_d,  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d)
+          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0
+          --  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+          --  S_d     = VZ.2 P_0 + VZ.3 Q_0
+          (Q, Z) := (VQ.1, VZ.1)
+          zero?(Q) => return construct(VZ.2, VZ.3, VZ.1)
+          VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
+          zero?(degree(Q)) => return construct(VZ.2, VZ.3, VZ.1)
+          ss : R := LC(VZ.1)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiLastSubResultantEuclidean(P : polR, Q : polR) :
+                    Record(coef2 : polR, subResultant : polR) == 
+       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+       degree(P) < degree(Q) =>
+              error("semiLastSubResultantEuclidean$PRS : bad degrees")
+       if zero?(degree(Q)) then
+          degP : NNI := degree(P)
+          zero?(degP) => 
+              error("semiLastSubResultantEuclidean$PRS : constant polynomials")
+          s : R := LC(Q)**(degP-1)::NNI
+          return construct(s::polR, s * Q)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+       VZ : Vector(polR) := copy(VP)
+       repeat
+          --  VZ.1 = S_d,  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d)
+          --  S_{c-1} = ... P_0 + VP.2 Q_0
+          --  S_{d-1} = ... P_0 + VQ.2 Q_0
+          --  S_d     = ... P_0 + VZ.2 Q_0
+          (Q, Z) := (VQ.1, VZ.1)
+          zero?(Q) => return construct(VZ.2, VZ.1)
+          VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
+          zero?(degree(Q)) => return construct(VZ.2, VZ.1)
+          ss : R := LC(VZ.1)
+          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    chainSubResultants(P : polR, Q : polR) : List(polR) ==
+       zero?(Q) or zero?(P) => []
+       if degree(P) < degree(Q) then 
+          (P, Q) := (Q, P)
+          if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
+       L : List(polR) := []
+       zero?(degree(Q)) => L
+       L := [Q]
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       repeat
+          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
+          -- L = [S_d,....,S_{q-1}]
+          zero?(Q) => return L
+          L := concat(Q, L)
+          -- L = [S_{d-1},....,S_{q-1}]
+          delta : NNI := (degree(P) - degree(Q))::NNI
+          Z : polR := Lazard2(Q, LC(Q), s, delta)            -- Z = S_e ~ S_d-1
+          if delta > 1 then L := concat(Z, L)
+          -- L = [S_e,....,S_{q-1}]
+          zero?(degree(Z)) => return L
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    schema(P : polR, Q : polR) : List(NNI) ==
+       zero?(Q) or zero?(P) => []
+       if degree(P) < degree(Q) then (P, Q) := (Q, P)
+       zero?(degree(Q)) => [0]
+       L : List(NNI) := []
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, Q))
+       repeat
+          -- P = S_{c-1} ~ S_d,  Q = S_{d-1},  s = lc(S_d)
+          zero?(Q) => return L
+          e : NNI := degree(Q)
+          L := concat(e, L)
+          delta : NNI := (degree(P) - e)::NNI
+          Z : polR := Lazard2(Q, LC(Q), s, delta)            -- Z = S_e ~ S_d-1
+          if delta > 1 then L := concat(e, L)
+          zero?(e) => return L
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+
+    subResultantGcd(P : polR, Q : polR) : polR == 
+       zero?(P) and zero?(Q) => 0
+       zero?(P) => Q
+       zero?(Q) => P
+       if degree(P) < degree(Q) then (P, Q) := (Q, P)
+       zero?(degree(Q)) => 1$polR
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       (P, Q) := (Q, pseudoRemainder(P, -Q))
+       repeat
+          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
+          zero?(Q) => return P
+          zero?(degree(Q)) => return 1$polR
+          Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI) 
+          -- Z = S_e ~ S_d-1
+          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+          s := LC(Z)
+            
+    subResultantGcdEuclidean(P : polR, Q : polR) :
+                    Record(coef1 : polR, coef2 : polR, gcd : polR) ==
+       zero?(P) and zero?(Q) => construct(0::polR, 0::polR, 0::polR)
+       zero?(P) => construct(0::polR, 1::polR, Q)
+       zero?(Q) => construct(1::polR, 0::polR, P)
+       if degree(P) < degree(Q) then 
+          l := subResultantGcdEuclidean(Q, P)
+          return construct(l.coef2, l.coef1, l.gcd)
+       zero?(degree(Q)) => construct(0::polR, 1::polR, Q)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 0::polR, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+       repeat
+          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(VP.2, VP.3, P)
+          e : NNI := degree(Q)
+          zero?(e) => return construct(VQ.2, VQ.3, Q)
+          ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
+          (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiSubResultantGcdEuclidean2(P : polR, Q : polR) :
+                                  Record(coef2 : polR, gcd : polR) ==
+       zero?(P) and zero?(Q) => construct(0::polR, 0::polR)
+       zero?(P) => construct(1::polR, Q)
+       zero?(Q) => construct(0::polR, P)
+       degree(P) < degree(Q) => 
+                       error("semiSubResultantGcdEuclidean2$PRS : bad degrees")
+       zero?(degree(Q)) => construct(1::polR, Q)
+       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+       VP : Vector(polR) := [Q, 1::polR]
+       pdiv := pseudoDivide(P, -Q)
+       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+       repeat
+          --  P=S_{c-1},  Q=S_{d-1},  s=lc(S_d)
+          --  S_{c-1} = ? P_0 + old_cf2 Q_0,  S_{d-1} = ? P_0 + cf2 Q_0
+          (P, Q) := (VP.1, VQ.1)
+          zero?(Q) => return construct(VP.2, P)
+          e : NNI := degree(Q)
+          zero?(e) => return construct(VQ.2, Q)
+          ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
+          (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+          s := ss
+
+    semiSubResultantGcdEuclidean1(P : polR, Q : polR) :
+                       Record(coef1 : polR, gcd : polR) ==
+       result := subResultantGcdEuclidean(P,Q)
+       [result.coef1, result.gcd]
+
+    discriminant(P : polR) : R ==
+       d : Integer := degree(P)
+       zero?(d) => error "cannot take discriminant of constants"
+       a : Integer := (d * (d-1)) quo 2
+       a := (-1)**a::NonNegativeInteger
+       dP : polR := differentiate P
+       r : R := resultant(P, dP)
+       d := d - degree(dP) - 1
+       return (if zero?(d) then a * (r exquo LC(P))::R
+               else a * r * LC(P)**(d-1)::NNI)
+
+    discriminantEuclidean(P : polR) : 
+                       Record(coef1 : polR, coef2 : polR, discriminant : R) ==
+       d : Integer := degree(P)
+       zero?(d) => error "cannot take discriminant of constants"
+       a : Integer := (d * (d-1)) quo 2
+       a := (-1)**a::NonNegativeInteger
+       dP : polR := differentiate P
+       rE := resultantEuclidean(P, dP)
+       d := d - degree(dP) - 1
+       if zero?(d) then 
+          c1 : polR := a * (rE.coef1 exquo LC(P))::polR
+          c2 : polR := a * (rE.coef2 exquo LC(P))::polR
+          cr : R := a * (rE.resultant exquo LC(P))::R
+       else
+          c1 : polR := a * rE.coef1 * LC(P)**(d-1)::NNI
+          c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
+          cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
+       return construct(c1, c2, cr)
+
+    semiDiscriminantEuclidean(P : polR) : 
+                            Record(coef2 : polR, discriminant : R) ==
+       d : Integer := degree(P)
+       zero?(d) => error "cannot take discriminant of constants"
+       a : Integer := (d * (d-1)) quo 2
+       a := (-1)**a::NonNegativeInteger
+       dP : polR := differentiate P
+       rE := semiResultantEuclidean2(P, dP)
+       d := d - degree(dP) - 1
+       if zero?(d) then 
+          c2 : polR := a * (rE.coef2 exquo LC(P))::polR
+          cr : R := a * (rE.resultant exquo LC(P))::R
+       else
+          c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
+          cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
+       return construct(c2, cr)
+
+    if R has GcdDomain then
+       resultantReduit(P : polR, Q : polR) : R ==
+          UV := subResultantGcdEuclidean(P, Q)
+          UVs : polR := UV.gcd
+          degree(UVs) > 0 => 0
+          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+          return (LC(UVs) exquo gcd(l))::R
+
+       resultantReduitEuclidean(P : polR, Q : polR) :
+                     Record(coef1 : polR, coef2 : polR, resultantReduit : R) ==
+          UV := subResultantGcdEuclidean(P, Q)
+          UVs : polR := UV.gcd
+          degree(UVs) > 0 => construct(0::polR, 0::polR, 0::R)
+          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+          gl : R := gcd(l)
+          c1 : polR := (UV.coef1 exquo gl)::polR
+          c2 : polR := (UV.coef2 exquo gl)::polR
+          rr : R := (LC(UVs) exquo gl)::R
+          return construct(c1, c2, rr)
+
+       semiResultantReduitEuclidean(P : polR, Q : polR) :
+                                   Record(coef2 : polR, resultantReduit : R) ==
+          UV := subResultantGcdEuclidean(P, Q)
+          UVs : polR := UV.gcd
+          degree(UVs) > 0 => construct(0::polR, 0::R)
+          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+          gl : R := gcd(l)
+          c2 : polR := (UV.coef2 exquo gl)::polR
+          rr : R := (LC(UVs) exquo gl)::R
+          return construct(c2, rr)
+
+       gcd_naif(P : polR, Q : polR) : polR ==
+       -- valid over a field
+          zero?(P) => (Q exquo LC(Q))::polR
+          repeat
+             zero?(Q) => return (P exquo LC(P))::polR
+             zero?(degree(Q)) => return 1$polR
+             (P, Q) := (Q, divide(P, Q).remainder)
+
+       gcd(P : polR, Q : polR) : polR ==
+          R has Finite => gcd_naif(P,Q) 
+          zero?(P) => Q
+          zero?(Q) => P
+          cP : R := content(P)
+          cQ : R := content(Q)
+          P := (P exquo cP)::polR
+          Q := (Q exquo cQ)::polR
+          G : polR := subResultantGcd(P, Q)
+          return gcd(cP,cQ) * primitivePart(G)
+
+@
+<<PRS.dotabb>>=
+"PRS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PRS"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"PRS" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package INTPAF PureAlgebraicIntegration}
 \pagehead{PureAlgebraicIntegration}{INTPAF}
 \pagepic{ps/v104purealgebraicintegration.ps}{INTPAF}{1.00}
@@ -59669,6 +67082,8 @@ RationalFunctionFactor(UP): Exports == Implementation where
 @
 <<RFFACT.dotabb>>=
 "RFFACT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=RFFACT"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"RFFACT" -> "ALIST"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -60342,6 +67757,7 @@ RealSolvePackage(): _
 @
 <<REALSOLV.dotabb>>=
 "REALSOLV" [color="#FF4488",href="bookvol10.4.pdf#nameddest=REALSOLV"]
+"Package" [color="#FF4488"]
 "REALSOLV" -> "Package"
 
 @
@@ -60420,6 +67836,70 @@ RectangularMatrixCategoryFunctions2(m,n,R1,Row1,Col1,M1,R2,Row2,Col2,M2):_
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package RDIV ReducedDivisor}
+\pagehead{ReducedDivisor}{RDIV}
+\pagepic{ps/v104reduceddivisor.ps}{RDIV}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package RDIV ReducedDivisor>>=
+)abbrev package RDIV ReducedDivisor
+++ Finds the order of a divisor over a finite field
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 8 November 1994
+ReducedDivisor(F1, UP, UPUP, R, F2): Exports == Implementation where
+  F1    : Field
+  UP    : UnivariatePolynomialCategory F1
+  UPUP  : UnivariatePolynomialCategory Fraction UP
+  R     : FunctionFieldCategory(F1, UP, UPUP)
+  F2    : Join(Finite, Field)
+
+  N     ==> NonNegativeInteger
+  FD    ==> FiniteDivisor(F1, UP, UPUP, R)
+  UP2   ==> SparseUnivariatePolynomial F2
+  UPUP2 ==> SparseUnivariatePolynomial Fraction UP2
+
+  Exports ==> with
+    order: (FD, UPUP, F1 -> F2) -> N
+	++ order(f,u,g) \undocumented
+
+  Implementation ==> add
+    algOrder : (FD, UPUP, F1 -> F2)  -> N
+    rootOrder: (FD, UP, N, F1 -> F2) -> N
+
+-- pp is not necessarily monic
+    order(d, pp, f) ==
+      (r := retractIfCan(reductum pp)@Union(Fraction UP, "failed"))
+        case "failed" => algOrder(d, pp, f)
+      rootOrder(d, - retract(r::Fraction(UP) / leadingCoefficient pp)@UP,
+                degree pp, f)
+
+    algOrder(d, modulus, reduce) ==
+      redmod := map(reduce, modulus)$MultipleMap(F1,UP,UPUP,F2,UP2,UPUP2)
+      curve  := AlgebraicFunctionField(F2, UP2, UPUP2, redmod)
+      order(map(reduce,
+              d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
+                                 )$FindOrderFinite(F2, UP2, UPUP2, curve)
+
+    rootOrder(d, radicand, n, reduce) ==
+      redrad := map(reduce,
+           radicand)$UnivariatePolynomialCategoryFunctions2(F1,UP,F2,UP2)
+      curve  := RadicalFunctionField(F2, UP2, UPUP2, redrad::Fraction UP2, n)
+      order(map(reduce,
+              d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
+                                 )$FindOrderFinite(F2, UP2, UPUP2, curve)
+
+@
+<<RDIV.dotabb>>=
+"RDIV" [color="#FF4488",href="bookvol10.4.pdf#nameddest=RDIV"]
+"FFCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FFCAT"]
+"RDIV" -> "FFCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ODERED ReduceLODE}
 \pagehead{ReduceLODE}{ODERED}
 \pagepic{ps/v104reducelode.ps}{ODERED}{1.00}
@@ -60786,6 +68266,8 @@ SAERationalFunctionAlgFactor(UP, SAE, UPA): Exports == Implementation where
 @
 <<SAERFFC.dotabb>>=
 "SAERFFC" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SAERFFC"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"SAERFFC" -> "MONOGEN"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -60877,6 +68359,8 @@ SimpleAlgebraicExtensionAlgFactor(UP,SAE,UPA):Exports==Implementation where
 @
 <<SAEFACT.dotabb>>=
 "SAEFACT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SAEFACT"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"SAEFACT" -> "MONOGEN"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -61001,6 +68485,51 @@ SortedCache(S:CachableSet): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package SUP2 SparseUnivariatePolynomialFunctions2}
+\pagehead{SparseUnivariatePolynomialFunctions2}{SUP2}
+\pagepic{ps/v104sparseunivariatepolynomialfunctions2.ps}{SUP2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package SUP2 SparseUnivariatePolynomialFunctions2>>=
+)abbrev package SUP2 SparseUnivariatePolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package lifts a mapping from coefficient rings R to S to
+++ a mapping from sparse univariate polynomial over R to
+++ a sparse univariate polynomial over S.
+++ Note that the mapping is assumed
+++ to send zero to zero, since it will only be applied to the non-zero
+++ coefficients of the polynomial.
+
+SparseUnivariatePolynomialFunctions2(R:Ring, S:Ring): with
+  map:(R->S,SparseUnivariatePolynomial R) -> SparseUnivariatePolynomial S
+    ++ map(func, poly) creates a new polynomial by applying func to
+    ++ every non-zero coefficient of the polynomial poly.
+ == add
+  map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
+           SparseUnivariatePolynomial R, S, SparseUnivariatePolynomial S)
+
+@
+<<SUP2.dotabb>>=
+"SUP2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SUP2"]
+"LMODULE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=LMODULE"]
+"SGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=SGROUP"]
+"SUP2" -> "LMODULE"
+"SUP2" -> "SGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package SPECOUT SpecialOutputPackage}
 \pagehead{SpecialOutputPackage}{SPECOUT}
 \pagepic{ps/v104specialoutputpackage.ps}{SPECOUT}{1.00}
@@ -65166,6 +72695,58 @@ UnivariateLaurentSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UPOLYC2 UnivariatePolynomialCategoryFunctions2}
+\pagehead{UnivariatePolynomialCategoryFunctions2}{UPOLYC2}
+\pagepic{ps/v104univariatepolynomialcategoryfunctions2.ps}{UPOLYC2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>=
+)abbrev package UPOLYC2 UnivariatePolynomialCategoryFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Mapping from polynomials over R to polynomials over S
+++ given a map from R to S assumed to send zero to zero.
+
+UnivariatePolynomialCategoryFunctions2(R,PR,S,PS): Exports == Impl where
+  R, S: Ring
+  PR  : UnivariatePolynomialCategory R
+  PS  : UnivariatePolynomialCategory S
+
+  Exports ==> with
+    map: (R -> S, PR) -> PS
+     ++ map(f, p) takes a function f from R to S,
+     ++ and applies it to each (non-zero) coefficient of a polynomial p
+     ++ over R, getting a new polynomial over S.
+     ++ Note: since the map is not applied to zero elements, it may map zero
+     ++ to zero.
+
+  Impl ==> add
+    map(f, p) ==
+      ans:PS := 0
+      while p ^= 0 repeat
+        ans := ans + monomial(f leadingCoefficient p, degree p)
+        p   := reductum p
+      ans
+
+@
+<<UPOLYC2.dotabb>>=
+"UPOLYC2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UPOLYC2"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"UPOLYC2" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package UPCDEN UnivariatePolynomialCommonDenominator}
 \pagehead{UnivariatePolynomialCommonDenominator}{UPCDEN}
 \pagepic{ps/v104univariatepolynomialcommondenominator.ps}{UPCDEN}{1.00}
@@ -65222,6 +72803,341 @@ UnivariatePolynomialCommonDenominator(R, Q, UP): Exports == Impl where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UP2 UnivariatePolynomialFunctions2}
+\pagehead{UnivariatePolynomialFunctions2}{UP2}
+\pagepic{ps/v104univariatepolynomialfunctions2.ps}{UP2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UP2 UnivariatePolynomialFunctions2>>=
+)abbrev package UP2 UnivariatePolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package lifts a mapping from coefficient rings R to S to
+++ a mapping from \spadtype{UnivariatePolynomial}(x,R) to
+++ \spadtype{UnivariatePolynomial}(y,S). Note that the mapping is assumed
+++ to send zero to zero, since it will only be applied to the non-zero
+++ coefficients of the polynomial.
+
+UnivariatePolynomialFunctions2(x:Symbol, R:Ring, y:Symbol, S:Ring): with
+  map: (R -> S, UnivariatePolynomial(x,R)) -> UnivariatePolynomial(y,S)
+    ++ map(func, poly) creates a new polynomial by applying func to
+    ++ every non-zero coefficient of the polynomial poly.
+ == add
+  map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
+              UnivariatePolynomial(x, R), S, UnivariatePolynomial(y, S))
+
+@
+<<UP2.dotabb>>=
+"UP2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UP2"]
+"LMODULE" [color="#4488FF",href="bookvol10.2.pdf#nameddest=LMODULE"]
+"SGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=SGROUP"]
+"UP2" -> "LMODULE"
+"UP2" -> "SGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UPMP UnivariatePolynomialMultiplicationPackage}
+\pagehead{UnivariatePolynomialMultiplicationPackage}{UPMP}
+\pagepic{ps/v104univariatepolynomialmultiplicationpackage.ps}{UPMP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UPMP UnivariatePolynomialMultiplicationPackage>>=
+)abbrev package UPMP UnivariatePolynomialMultiplicationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 14.08.2000
+++ Description:
+++ This package implements Karatsuba's trick for multiplying
+++ (large) univariate polynomials. It could be improved with
+++ a version doing the work on place and also with a special
+++ case for squares. We've done this in Basicmath, but we
+++ believe that this out of the scope of AXIOM.
+
+UnivariatePolynomialMultiplicationPackage(R: Ring, U: UnivariatePolynomialCategory(R)): C == T
+  where
+    HL ==> Record(quotient:U,remainder:U)
+    C == with
+      noKaratsuba: (U, U) -> U
+        ++ \spad{noKaratsuba(a,b)} returns \spad{a*b} without
+        ++ using Karatsuba's trick at all.
+      karatsubaOnce: (U, U) -> U
+        ++ \spad{karatsuba(a,b)} returns \spad{a*b} by applying
+        ++ Karatsuba's trick once. The other multiplications
+        ++ are performed by calling \spad{*} from \spad{U}.
+      karatsuba: (U, U, NonNegativeInteger, NonNegativeInteger) -> U;
+        ++ \spad{karatsuba(a,b,l,k)} returns \spad{a*b} by applying
+        ++ Karatsuba's trick provided that both \spad{a} and \spad{b}
+        ++ have at least \spad{l} terms and \spad{k > 0} holds
+        ++ and by calling \spad{noKaratsuba} otherwise. The other
+        ++ multiplications are performed by recursive calls with
+        ++ the same third argument and \spad{k-1} as fourth argument.
+
+    T == add
+      noKaratsuba(a,b) ==
+        zero? a => a
+        zero? b => b
+        zero?(degree(a)) => leadingCoefficient(a) * b
+        zero?(degree(b)) => a * leadingCoefficient(b)
+        lu: List(U) := reverse monomials(a)
+        res: U := 0;
+        for u in lu repeat
+          res := pomopo!(res, leadingCoefficient(u), degree(u), b)
+        res
+      karatsubaOnce(a:U,b:U): U ==
+        da := minimumDegree(a)
+        db := minimumDegree(b)
+        if not zero? da then a := shiftRight(a,da)
+        if not zero? db then b := shiftRight(b,db)
+        d := da + db
+        n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
+        rec: HL := karatsubaDivide(a, n)
+        ha := rec.quotient
+        la := rec.remainder
+        rec := karatsubaDivide(b, n)
+        hb := rec.quotient
+        lb := rec.remainder
+        w: U := (ha - la) * (lb - hb)
+        u: U := la * lb
+        v: U := ha * hb
+        w := w + (u + v)
+        w := shiftLeft(w,n) + u
+        zero? d => shiftLeft(v,2*n) + w
+        shiftLeft(v,2*n + d) + shiftLeft(w,d)
+      karatsuba(a:U,b:U,l:NonNegativeInteger,k:NonNegativeInteger): U ==
+        zero? k => noKaratsuba(a,b)
+        degree(a) < l => noKaratsuba(a,b)
+        degree(b) < l => noKaratsuba(a,b)
+        numberOfMonomials(a) < l => noKaratsuba(a,b)
+        numberOfMonomials(b) < l => noKaratsuba(a,b)
+        da := minimumDegree(a)
+        db := minimumDegree(b)
+        if not zero? da then a := shiftRight(a,da)
+        if not zero? db then b := shiftRight(b,db)
+        d := da + db
+        n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
+        k := subtractIfCan(k,1)::NonNegativeInteger
+        rec: HL := karatsubaDivide(a, n)
+        ha := rec.quotient
+        la := rec.remainder
+        rec := karatsubaDivide(b, n)
+        hb := rec.quotient
+        lb := rec.remainder
+        w: U := karatsuba(ha - la, lb - hb, l, k)
+        u: U := karatsuba(la, lb, l, k)
+        v: U := karatsuba(ha, hb, l, k)
+        w := w + (u + v)
+        w := shiftLeft(w,n) + u
+        zero? d => shiftLeft(v,2*n) + w
+        shiftLeft(v,2*n + d) + shiftLeft(w,d)
+
+@
+<<UPMP.dotabb>>=
+"UPMP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UPMP"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"UPMP" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UPSQFREE UnivariatePolynomialSquareFree}
+\pagehead{UnivariatePolynomialSquareFree}{UPSQFREE}
+\pagepic{ps/v104univariatepolynomialsquarefree.ps}{UPSQFREE}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UPSQFREE UnivariatePolynomialSquareFree>>=
+)abbrev package UPSQFREE UnivariatePolynomialSquareFree
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: squareFree, squareFreePart
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides for square-free decomposition of
+++ univariate polynomials over arbitrary rings, i.e.
+++ a partial factorization such that each factor is a product
+++ of irreducibles with multiplicity one and the factors are
+++ pairwise relatively prime. If the ring
+++ has characteristic zero, the result is guaranteed to satisfy
+++ this condition. If the ring is an infinite ring of
+++ finite characteristic, then it may not be possible to decide when
+++ polynomials contain factors which are pth powers. In this
+++ case, the flag associated with that polynomial is set to "nil"
+++ (meaning that that polynomials are not guaranteed to be square-free).
+
+UnivariatePolynomialSquareFree(RC:IntegralDomain,P):C == T
+  where
+    fUnion ==> Union("nil", "sqfr", "irred", "prime")
+    FF     ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
+    P:Join(UnivariatePolynomialCategory(RC),IntegralDomain) with
+      gcd: (%,%) -> %
+        ++ gcd(p,q) computes the greatest-common-divisor of p and q.
+
+    C == with
+      squareFree: P -> Factored(P)
+        ++ squareFree(p) computes the square-free factorization of the
+        ++ univariate polynomial p. Each factor has no repeated roots, and the
+        ++ factors are pairwise relatively prime.
+      squareFreePart: P -> P
+        ++ squareFreePart(p) returns a polynomial which has the same
+        ++ irreducible factors as the univariate polynomial p, but each
+        ++ factor has multiplicity one.
+      BumInSepFFE: FF -> FF
+        ++ BumInSepFFE(f) is a local function, exported only because
+        ++ it has multiple conditional definitions.
+
+    T == add
+
+      if RC has CharacteristicZero then
+        squareFreePart(p:P) == (p exquo gcd(p, differentiate p))::P
+      else
+        squareFreePart(p:P) ==
+          unit(s := squareFree(p)$%) * */[f.factor for f in factors s]
+
+      if RC has FiniteFieldCategory then
+        BumInSepFFE(ffe:FF) ==
+           ["sqfr", map(charthRoot,ffe.fctr), characteristic$P*ffe.xpnt]
+      else if RC has CharacteristicNonZero then
+         BumInSepFFE(ffe:FF) ==
+            np := multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger)
+            (nthrp := charthRoot(np)) case "failed" =>
+               ["nil", np, ffe.xpnt]
+            ["sqfr", nthrp, characteristic$P*ffe.xpnt]
+
+      else
+        BumInSepFFE(ffe:FF) ==
+          ["nil",
+           multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger),
+            ffe.xpnt]
+
+
+      if RC has CharacteristicZero then
+        squareFree(p:P) ==             --Yun's algorithm - see SYMSAC '76, p.27
+           --Note ci primitive is, so GCD's don't need to %do contents.
+           --Change gcd to return cofctrs also?
+           ci:=p; di:=differentiate(p); pi:=gcd(ci,di)
+           degree(pi)=0 =>
+             (u,c,a):=unitNormal(p)
+             makeFR(u,[["sqfr",c,1]])
+           i:NonNegativeInteger:=0; lffe:List FF:=[]
+           lcp := leadingCoefficient p
+           while degree(ci)^=0 repeat
+              ci:=(ci exquo pi)::P
+              di:=(di exquo pi)::P - differentiate(ci)
+              pi:=gcd(ci,di)
+              i:=i+1
+              degree(pi) > 0 =>
+                 lcp:=(lcp exquo (leadingCoefficient(pi)**i))::RC
+                 lffe:=[["sqfr",pi,i],:lffe]
+           makeFR(lcp::P,lffe)
+
+      else
+        squareFree(p:P) ==           --Musser's algorithm - see SYMSAC '76, p.27
+             --p MUST BE PRIMITIVE, Any characteristic.
+             --Note ci primitive, so GCD's don't need to %do contents.
+             --Change gcd to return cofctrs also?
+           ci := gcd(p,differentiate(p))
+           degree(ci)=0 =>
+             (u,c,a):=unitNormal(p)
+             makeFR(u,[["sqfr",c,1]])
+           di := (p exquo ci)::P
+           i:NonNegativeInteger:=0; lffe:List FF:=[]
+           dunit : P := 1
+           while degree(di)^=0 repeat
+              diprev := di
+              di := gcd(ci,di)
+              ci:=(ci exquo di)::P
+              i:=i+1
+              degree(diprev) = degree(di) =>
+                 lc := (leadingCoefficient(diprev) exquo leadingCoefficient(di))::RC
+                 dunit := lc**i * dunit
+              pi:=(diprev exquo di)::P
+              lffe:=[["sqfr",pi,i],:lffe]
+           dunit := dunit * di ** (i+1)
+           degree(ci)=0 => makeFR(dunit*ci,lffe)
+           redSqfr:=squareFree(divideExponents(ci,characteristic$P)::P)
+           lsnil:= [BumInSepFFE(ffe) for ffe in factorList redSqfr]
+           lffe:=append(lsnil,lffe)
+           makeFR(dunit*(unit redSqfr),lffe)
+
+@
+<<UPSQFREE.dotabb>>=
+"UPSQFREE" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UPSQFREE"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"UPSQFREE" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UPXS2 UnivariatePuiseuxSeriesFunctions2}
+\pagehead{UnivariatePuiseuxSeriesFunctions2}{UPXS2}
+\pagepic{ps/v104univariatepuiseuxseriesfunctions2.ps}{UPXS2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>=
+)abbrev package UPXS2 UnivariatePuiseuxSeriesFunctions2
+++ Mapping package for univariate Puiseux series
+++ Author: Scott C. Morrison
+++ Date Created: 5 April 1991
+++ Date Last Updated: 5 April 1991
+++ Keywords: Puiseux series, map
+++ Examples:
+++ References:
+++ Description:
+++   Mapping package for univariate Puiseux series.
+++   This package allows one to apply a function to the coefficients of
+++   a univariate Puiseux series.
+UnivariatePuiseuxSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
+ Exports == Implementation where
+  Coef1 : Ring
+  Coef2 : Ring
+  var1: Symbol
+  var2: Symbol
+  cen1: Coef1
+  cen2: Coef2
+  UPS1  ==> UnivariatePuiseuxSeries(Coef1, var1, cen1)
+  UPS2  ==> UnivariatePuiseuxSeries(Coef2, var2, cen2)
+  ULSP2 ==> UnivariateLaurentSeriesFunctions2(Coef1, Coef2, var1, var2, cen1, cen2)
+
+  Exports ==> with
+    map: (Coef1 -> Coef2,UPS1) -> UPS2
+      ++ \spad{map(f,g(x))} applies the map f to the coefficients of the
+      ++ Puiseux series \spad{g(x)}.
+
+  Implementation ==> add
+
+    map(f,ups) == puiseux(rationalPower ups, map(f, laurentRep ups)$ULSP2)
+
+@
+<<UPXS2.dotabb>>=
+"UPXS2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UPXS2"]
+"PID" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PID"]
+"OAGROUP" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OAGROUP"]
+"UPXS2" -> "PID"
+"UPXS2" -> "OAGROUP"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package OREPCTO UnivariateSkewPolynomialCategoryOps}
 \pagehead{UnivariateSkewPolynomialCategoryOps}{OREPCTO}
 \pagepic{ps/v104univariateskewpolynomialcategoryops.ps}{OREPCTO}{1.00}
@@ -65697,10 +73613,12 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package CHVAR ChangeOfVariable>>
 <<package CPIMA CharacteristicPolynomialInMonogenicalAlgebra>>
 <<package CHARPOL CharacteristicPolynomialPackage>>
+<<package IBACHIN ChineseRemainderToolsForIntegralBases>>
 <<package CVMP CoerceVectorMatrixPackage>>
 <<package COMBF CombinatorialFunction>>
 <<package CDEN CommonDenominator>>
 <<package COMMONOP CommonOperators>>
+<<package COMMUPC CommuteUnivariatePolynomialCategory>>
 <<package COMPFACT ComplexFactorization>>
 <<package COMPLEX2 ComplexFunctions2>>
 <<package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation>>
@@ -65759,6 +73677,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package FR2 FactoredFunctions2>>
 <<package FRUTIL FactoredFunctionUtilities>>
 <<package FACUTIL FactoringUtilities>>
+<<package FORDER FindOrderFinite>>
 <<package FAMR2 FiniteAbelianMonoidRingFunctions2>>
 <<package FDIV2 FiniteDivisorFunctions2>>
 <<package FFF FiniteFieldFunctions>>
@@ -65787,6 +73706,8 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package FSCINT FunctionSpaceComplexIntegration>>
 <<package FS2 FunctionSpaceFunctions2>>
 <<package FSINT FunctionSpaceIntegration>>
+<<package FSPRMELT FunctionSpacePrimitiveElement>>
+<<package FSRED FunctionSpaceReduce>>
 <<package SUMFS FunctionSpaceSum>>
 <<package FS2EXPXP FunctionSpaceToExponentialExpansion>>
 <<package FS2UPS FunctionSpaceToUnivariatePowerSeries>>
@@ -65805,6 +73726,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package GENUFACT GenUFactorize>>
 <<package INTG0 GenusZeroIntegration>>
 <<package GRDEF GraphicsDefaults>>
+<<package GRAY GrayCode>>
 <<package GBF GroebnerFactorizationPackage>>
 <<package GBINTERN GroebnerInternalPackage>>
 <<package GB GroebnerPackage>>
@@ -65847,6 +73769,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package IROOT IntegerRoots>>
 <<package INTSLPE IntegerSolveLinearPolynomialEquation>>
 <<package IBATOOL IntegralBasisTools>>
+<<package IBPTOOLS IntegralBasisPolynomialTools>>
 <<package IR2 IntegrationResultFunctions2>>
 <<package IRRF2F IntegrationResultRFToFunction>>
 <<package IR2F IntegrationResultToFunction>>
@@ -65895,6 +73818,8 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package MONOTOOL MonomialExtensionTools>>
 <<package MPCPF MPolyCatPolyFactorizer>>
 <<package MPRFF MPolyCatRationalFunctionFactorizer>>
+<<package MPC2 MPolyCatFunctions2>>
+<<package MPC3 MPolyCatFunctions3>>
 <<package MRATFAC MRationalFactorize>>
 <<package MFINFACT MultFiniteFactorize>>
 <<package MMAP MultipleMap>>
@@ -65947,19 +73872,64 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package OPQUERY OperationsQuery>>
 <<package OUT OutputPackage>>
 
+<<package PADEPAC PadeApproximantPackage>>
+<<package PADE PadeApproximants>>
+<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>
+<<package PLEQN ParametricLinearEquations>>
+<<package PARPC2 ParametricPlaneCurveFunctions2>>
+<<package PARSC2 ParametricSpaceCurveFunctions2>>
+<<package PARSU2 ParametricSurfaceFunctions2>>
+<<package PFRPAC PartialFractionPackage>>
+<<package PARTPERM PartitionsAndPermutations>>
+<<package PATTERN1 PatternFunctions1>>
+<<package PATTERN2 PatternFunctions2>>
+<<package PATMATCH PatternMatch>>
 <<package PMASS PatternMatchAssertions>>
+<<package PMFS PatternMatchFunctionSpace>>
+<<package PMINS PatternMatchIntegerNumberSystem>>
 <<package INTPM PatternMatchIntegration>>
+<<package PMKERNEL PatternMatchKernel>>
+<<package PMLSAGG PatternMatchListAggregate>>
+<<package PMPLCAT PatternMatchPolynomialCategory>>
+<<package PMDOWN PatternMatchPushDown>>
+<<package PMQFCAT PatternMatchQuotientFieldCategory>>
+<<package PATRES2 PatternMatchResultFunctions2>>
+<<package PMSYM PatternMatchSymbol>>
+<<package PMTOOLS PatternMatchTools>>
+<<package PERMAN Permanent>>
+<<package PGE PermutationGroupExamples>>
 <<package PICOERCE PiCoercions>>
+<<package PLOT1 PlotFunctions1>>
+<<package PLOTTOOL PlotTools>>
 <<package PTFUNC2 PointFunctions2>>
 <<package PTPACK PointPackage>>
+<<package PFO PointsOfFiniteOrder>>
+<<package PFOQ PointsOfFiniteOrderRational>>
+<<package PFOTOOLS PointsOfFiniteOrderTools>>
+<<package POLTOPOL PolToPol>>
+<<package PGROEB PolyGroebner>>
 <<package PAN2EXPR PolynomialAN2Expression>>
+<<package POLYLIFT PolynomialCategoryLifting>>
+<<package PCOMP PolynomialComposition>>
+<<package PDECOMP PolynomialDecomposition>>
+<<package PFBR PolynomialFactorizationByRecursion>>
+<<package PFBRU PolynomialFactorizationByRecursionUnivariate>>
 <<package POLY2 PolynomialFunctions2>>
+<<package PGCD PolynomialGcdPackage>>
+<<package PINTERP PolynomialInterpolation>>
+<<package PINTERPA PolynomialInterpolationAlgorithms>>
 <<package PNTHEORY PolynomialNumberTheoryFunctions>>
 <<package POLYROOT PolynomialRoots>>
+<<package PSQFR PolynomialSquareFree>>
+<<package POLY2UP PolynomialToUnivariatePolynomial>>
 <<package LIMITPS PowerSeriesLimitPackage>>
 <<package PREASSOC PrecomputedAssociatedEquations>>
 <<package PRIMARR2 PrimitiveArrayFunctions2>>
+<<package PRIMELT PrimitiveElement>>
 <<package ODEPRIM PrimitiveRatDE>>
+<<package PRINT PrintPackage>>
+<<package PSEUDLIN PseudoLinearNormalForm>>
+<<package PRS PseudoRemainderSequence>>
 <<package INTPAF PureAlgebraicIntegration>>
 <<package ODEPAL PureAlgebraicLODE>>
 <<package PUSHVAR PushVariables>>
@@ -65974,6 +73944,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package ODERAT RationalLODE>>
 <<package REALSOLV RealSolvePackage>>
 <<package RMCAT2 RectangularMatrixCategoryFunctions2>>
+<<package RDIV ReducedDivisor>>
 <<package ODERED ReduceLODE>>
 <<package REDORDER ReductionOfOrder>>
 <<package REPDB RepeatedDoubling>>
@@ -65985,6 +73956,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package SAEFACT SimpleAlgebraicExtensionAlgFactor>>
 <<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>
 <<package SCACHE SortedCache>>
+<<package SUP2 SparseUnivariatePolynomialFunctions2>>
 <<package SPECOUT SpecialOutputPackage>>
 <<package MATSTOR StorageEfficientMatrixOperations>>
 <<package STINPROD StreamInfiniteProduct>>
@@ -66010,7 +73982,12 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 
 <<package UFPS1 UnivariateFormalPowerSeriesFunctions>>
 <<package ULS2 UnivariateLaurentSeriesFunctions2>>
+<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>
 <<package UPCDEN UnivariatePolynomialCommonDenominator>>
+<<package UP2 UnivariatePolynomialFunctions2>>
+<<package UPMP UnivariatePolynomialMultiplicationPackage>>
+<<package UPSQFREE UnivariatePolynomialSquareFree>>
+<<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>
 <<package OREPCTO UnivariateSkewPolynomialCategoryOps>>
 <<package UTSODETL UTSodetools>>
 
@@ -66022,3 +73999,4 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \printindex
 \end{document}
+
diff --git a/books/ps/v104algebraicfunction.ps b/books/ps/v104algebraicfunction.ps
index ecb09c0..a1dc8bd 100644
--- a/books/ps/v104algebraicfunction.ps
+++ b/books/ps/v104algebraicfunction.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 98 152
+%%PageBoundingBox: 36 36 170 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 62 116 boxprim clip newpath
+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
@@ -200,28 +200,28 @@ newpath -4 -4 moveto
 closepath stroke
 % AF
 gsave
-[ /Rect [ 0 72 54 108 ]
+[ /Rect [ 36 72 90 108 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=AF) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 54 108 moveto
-0 108 lineto
-0 72 lineto
-54 72 lineto
+newpath 90 108 moveto
+36 108 lineto
+36 72 lineto
+90 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 54 108 moveto
-0 108 lineto
-0 72 lineto
-54 72 lineto
+newpath 90 108 moveto
+36 108 lineto
+36 72 lineto
+90 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-18.5 86.4 moveto 17 (AF) alignedtext
+14.00 /Times-Roman set_font
+54.5 85.9 moveto 17 (AF) alignedtext
 grestore
 % FS
 gsave
@@ -232,40 +232,85 @@ gsave
 /ANN pdfmark
 0.606 0.733 1.000 nodecolor
 newpath 54 36 moveto
-0 36 lineto
-0 0 lineto
+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
-0 36 lineto
-0 0 lineto
+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 /Times-Roman set_font
-19.5 14.4 moveto 15 (FS) alignedtext
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 15 (FS) alignedtext
 grestore
 % AF->FS
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 27 72 moveto
-27 64 27 55 27 46 curveto
+newpath 54 72 moveto
+50 64 45 54 40 45 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 30.5 46 moveto
-27 36 lineto
-23.5 46 lineto
+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 30.5 46 moveto
-27 36 lineto
-23.5 46 lineto
+newpath 43.2598 43.7166 moveto
+36 36 lineto
+36.8631 46.5596 lineto
+closepath stroke
+grestore
+% ACF
+gsave
+[ /Rect [ 72 0 126 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 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
+85.5 13.9 moveto 27 (ACF) alignedtext
+grestore
+% AF->ACF
+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
@@ -275,7 +320,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 98 152
+%%BoundingBox: 36 36 170 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104algfactor.ps b/books/ps/v104algfactor.ps
index df5d091..e7da149 100644
--- a/books/ps/v104algfactor.ps
+++ b/books/ps/v104algfactor.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 122 152
+%%PageBoundingBox: 36 36 124 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 86 116 boxprim clip newpath
+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
@@ -200,72 +200,72 @@ newpath -4 -4 moveto
 closepath stroke
 % ALGFACT
 gsave
-[ /Rect [ 0 72 78 108 ]
+[ /Rect [ 0 72 80 108 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ALGFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 78 108 moveto
-0 108 lineto
-0 72 lineto
-78 72 lineto
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 78 108 moveto
-0 108 lineto
-0 72 lineto
-78 72 lineto
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-8 86.4 moveto 62 (ALGFACT) alignedtext
+14.00 /Times-Roman set_font
+8 85.9 moveto 64 (ALGFACT) alignedtext
 grestore
 % ACF
 gsave
-[ /Rect [ 12 0 66 36 ]
+[ /Rect [ 13 0 67 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 66 36 moveto
-12 36 lineto
-12 0 lineto
-66 0 lineto
+newpath 67 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+67 0 lineto
 closepath fill
 1 setlinewidth
 filled
 0.606 0.733 1.000 nodecolor
-newpath 66 36 moveto
-12 36 lineto
-12 0 lineto
-66 0 lineto
+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 /Times-Roman set_font
-26 14.4 moveto 26 (ACF) alignedtext
+14.00 /Times-Roman set_font
+26.5 13.9 moveto 27 (ACF) alignedtext
 grestore
 % ALGFACT->ACF
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 39 72 moveto
-39 64 39 55 39 46 curveto
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 42.5 46 moveto
-39 36 lineto
-35.5 46 lineto
+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 42.5 46 moveto
-39 36 lineto
-35.5 46 lineto
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 122 152
+%%BoundingBox: 36 36 124 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104chineseremaindertoolsforintegralbases.ps b/books/ps/v104chineseremaindertoolsforintegralbases.ps
new file mode 100644
index 0000000..1c30821
--- /dev/null
+++ b/books/ps/v104chineseremaindertoolsforintegralbases.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
+% IBACHIN
+gsave
+[ /Rect [ 8 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=IBACHIN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+8 108 lineto
+8 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+8 108 lineto
+8 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+15.5 85.9 moveto 57 (IBACHIN) alignedtext
+grestore
+% MONOGEN
+gsave
+[ /Rect [ 0 0 88 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 73 (MONOGEN) alignedtext
+grestore
+% IBACHIN->MONOGEN
+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/v104commuteunivariatepolynomialcategory.ps b/books/ps/v104commuteunivariatepolynomialcategory.ps
new file mode 100644
index 0000000..817801d
--- /dev/null
+++ b/books/ps/v104commuteunivariatepolynomialcategory.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
+% COMMUPC
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=COMMUPC) >>
+  /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 (COMMUPC) 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
+% COMMUPC->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/v104expertsystemcontinuitypackage1.ps b/books/ps/v104expertsystemcontinuitypackage1.ps
index 4411cc7..e709586 100644
--- a/books/ps/v104expertsystemcontinuitypackage1.ps
+++ b/books/ps/v104expertsystemcontinuitypackage1.ps
@@ -225,7 +225,7 @@ closepath stroke
 grestore
 % Package
 gsave
-0.000 0.000 1.000 nodecolor
+0.939 0.733 1.000 nodecolor
 newpath 72 36 moveto
 6 36 lineto
 6 1.06581e-14 lineto
@@ -233,7 +233,7 @@ newpath 72 36 moveto
 closepath fill
 1 setlinewidth
 filled
-0.000 0.000 1.000 nodecolor
+0.939 0.733 1.000 nodecolor
 newpath 72 36 moveto
 6 36 lineto
 6 1.06581e-14 lineto
diff --git a/books/ps/v104findorderfinite.ps b/books/ps/v104findorderfinite.ps
new file mode 100644
index 0000000..c0b40af
--- /dev/null
+++ b/books/ps/v104findorderfinite.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
+% FORDER
+gsave
+[ /Rect [ 0 72 70 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=FORDER) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.73566e-14 108 lineto
+6.33868e-15 72 lineto
+70 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.73566e-14 108 lineto
+6.33868e-15 72 lineto
+70 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 55 (FORDER) alignedtext
+grestore
+% FFCAT
+gsave
+[ /Rect [ 6 0 64 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FFCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 64 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+64 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 64 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+64 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14 13.9 moveto 42 (FFCAT) alignedtext
+grestore
+% FORDER->FFCAT
+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/v104functionspaceprimitiveelement.ps b/books/ps/v104functionspaceprimitiveelement.ps
new file mode 100644
index 0000000..15f58b5
--- /dev/null
+++ b/books/ps/v104functionspaceprimitiveelement.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
+% FSPRMELT
+gsave
+[ /Rect [ 0 72 84 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=FSPRMELT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.63123e-14 108 lineto
+5.2458e-15 72 lineto
+84 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 84 108 moveto
+2.63123e-14 108 lineto
+5.2458e-15 72 lineto
+84 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 69 (FSPRMELT) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 15 0 69 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 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
+34.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% FSPRMELT->FS
+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/v104functionspacereduce.ps b/books/ps/v104functionspacereduce.ps
new file mode 100644
index 0000000..8a2b189
--- /dev/null
+++ b/books/ps/v104functionspacereduce.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 102 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 66 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
+% FSRED
+gsave
+[ /Rect [ 0 72 58 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=FSRED) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 58 108 moveto
+1.96232e-14 108 lineto
+2.15973e-15 72 lineto
+58 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 58 108 moveto
+1.96232e-14 108 lineto
+2.15973e-15 72 lineto
+58 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 43 (FSRED) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 2 0 56 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 56 36 moveto
+2 36 lineto
+2 1.06581e-14 lineto
+56 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 56 36 moveto
+2 36 lineto
+2 1.06581e-14 lineto
+56 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+21.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% FSRED->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 29 72 moveto
+29 64 29 55 29 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 102 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104graycode.ps b/books/ps/v104graycode.ps
new file mode 100644
index 0000000..9b4c5d5
--- /dev/null
+++ b/books/ps/v104graycode.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
+% GRAY
+gsave
+[ /Rect [ 12 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GRAY) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+12 108 lineto
+12 72 lineto
+66 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+12 108 lineto
+12 72 lineto
+66 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20 85.9 moveto 38 (GRAY) alignedtext
+grestore
+% IVECTOR
+gsave
+[ /Rect [ 0 0 78 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 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 62 (IVECTOR) alignedtext
+grestore
+% GRAY->IVECTOR
+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/v104inneralgfactor.ps b/books/ps/v104inneralgfactor.ps
index bcd6a30..6afe526 100644
--- a/books/ps/v104inneralgfactor.ps
+++ b/books/ps/v104inneralgfactor.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 130 152
+%%PageBoundingBox: 36 36 132 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 94 116 boxprim clip newpath
+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
@@ -200,72 +200,72 @@ newpath -4 -4 moveto
 closepath stroke
 % IALGFACT
 gsave
-[ /Rect [ 2 72 84 108 ]
+[ /Rect [ 2 72 86 108 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=IALGFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 84 108 moveto
+newpath 86 108 moveto
 2 108 lineto
 2 72 lineto
-84 72 lineto
+86 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 84 108 moveto
+newpath 86 108 moveto
 2 108 lineto
 2 72 lineto
-84 72 lineto
+86 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-9.5 86.4 moveto 67 (IALGFACT) alignedtext
+14.00 /Times-Roman set_font
+10 85.9 moveto 68 (IALGFACT) alignedtext
 grestore
 % MONOGEN
 gsave
-[ /Rect [ 0 0 86 36 ]
+[ /Rect [ 0 0 88 36 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
   /Subtype /Link
 /ANN pdfmark
 0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
 closepath fill
 1 setlinewidth
 filled
 0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-8 14.4 moveto 70 (MONOGEN) alignedtext
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 73 (MONOGEN) alignedtext
 grestore
 % IALGFACT->MONOGEN
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 43 72 moveto
-43 64 43 55 43 46 curveto
+newpath 44 72 moveto
+44 64 44 55 44 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+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 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 130 152
+%%BoundingBox: 36 36 132 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104integralbasispolynomialtools.ps b/books/ps/v104integralbasispolynomialtools.ps
new file mode 100644
index 0000000..2b9978a
--- /dev/null
+++ b/books/ps/v104integralbasispolynomialtools.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
+% IBPTOOLS
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=IBPTOOLS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 67 (IBPTOOLS) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 8 0 74 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 74 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+74 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 74 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+74 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+15.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% IBPTOOLS->PFECAT
+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/v104mpolycatfunctions2.ps b/books/ps/v104mpolycatfunctions2.ps
new file mode 100644
index 0000000..6d0a6c1
--- /dev/null
+++ b/books/ps/v104mpolycatfunctions2.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
+% MPC2
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=MPC2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 85.9 moveto 37 (MPC2) 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
+% MPC2->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/v104mpolycatfunctions3.ps b/books/ps/v104mpolycatfunctions3.ps
new file mode 100644
index 0000000..6d0a6c1
--- /dev/null
+++ b/books/ps/v104mpolycatfunctions3.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
+% MPC2
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=MPC2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 85.9 moveto 37 (MPC2) 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
+% MPC2->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/v104nagpolynomialrootspackage.ps b/books/ps/v104nagpolynomialrootspackage.ps
index 610885b..36d66ed 100644
--- a/books/ps/v104nagpolynomialrootspackage.ps
+++ b/books/ps/v104nagpolynomialrootspackage.ps
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 114 152
+%%PageBoundingBox: 36 36 124 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 78 116 boxprim clip newpath
+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
@@ -198,74 +198,74 @@ newpath -4 -4 moveto
 536 716 lineto
 536 -4 lineto
 closepath stroke
-% NAGC02
+% MRATFAC
 gsave
-[ /Rect [ 0 72 70 108 ]
+[ /Rect [ 0 72 80 108 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=NAGC02) >>
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=MRATFAC) >>
   /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
+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 70 108 moveto
-2.13163e-14 108 lineto
-7.10543e-15 72 lineto
-70 72 lineto
+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
-8 85.9 moveto 54 (NAGC02) alignedtext
+7.5 85.9 moveto 65 (MRATFAC) alignedtext
 grestore
-% ALIST
+% PFECAT
 gsave
-[ /Rect [ 8 0 62 36 ]
+[ /Rect [ 7 0 73 36 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
   /Subtype /Link
 /ANN pdfmark
-0.273 0.733 1.000 nodecolor
-newpath 62 36 moveto
-8 36 lineto
-8 1.06581e-14 lineto
-62 0 lineto
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
 closepath fill
 1 setlinewidth
 filled
-0.273 0.733 1.000 nodecolor
-newpath 62 36 moveto
-8 36 lineto
-8 1.06581e-14 lineto
-62 0 lineto
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
 14.00 /Times-Roman set_font
-15.5 13.9 moveto 39 (ALIST) alignedtext
+14.5 13.9 moveto 51 (PFECAT) alignedtext
 grestore
-% NAGC02->ALIST
+% MRATFAC->PFECAT
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 35 72 moveto
-35 64 35 55 35 46 curveto
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 38.5001 46 moveto
-35 36 lineto
-31.5001 46 lineto
+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 38.5001 46 moveto
-35 36 lineto
-31.5001 46 lineto
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 114 152
+%%BoundingBox: 36 36 124 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104nagrootfindingpackage.ps b/books/ps/v104nagrootfindingpackage.ps
index 3e8c3ed..36d66ed 100644
--- a/books/ps/v104nagrootfindingpackage.ps
+++ b/books/ps/v104nagrootfindingpackage.ps
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 114 152
+%%PageBoundingBox: 36 36 124 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 78 116 boxprim clip newpath
+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
@@ -198,74 +198,74 @@ newpath -4 -4 moveto
 536 716 lineto
 536 -4 lineto
 closepath stroke
-% NAGC05
+% MRATFAC
 gsave
-[ /Rect [ 0 72 70 108 ]
+[ /Rect [ 0 72 80 108 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=NAGC05) >>
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=MRATFAC) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 70 108 moveto
-2.73566e-14 108 lineto
-6.33868e-15 72 lineto
-70 72 lineto
+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 70 108 moveto
-2.73566e-14 108 lineto
-6.33868e-15 72 lineto
-70 72 lineto
+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 55 (NAGC05) alignedtext
+7.5 85.9 moveto 65 (MRATFAC) alignedtext
 grestore
-% ALIST
+% PFECAT
 gsave
-[ /Rect [ 8 0 62 36 ]
+[ /Rect [ 7 0 73 36 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
   /Subtype /Link
 /ANN pdfmark
-0.273 0.733 1.000 nodecolor
-newpath 62 36 moveto
-8 36 lineto
-8 1.06581e-14 lineto
-62 0 lineto
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
 closepath fill
 1 setlinewidth
 filled
-0.273 0.733 1.000 nodecolor
-newpath 62 36 moveto
-8 36 lineto
-8 1.06581e-14 lineto
-62 0 lineto
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
 14.00 /Times-Roman set_font
-15.5 13.9 moveto 39 (ALIST) alignedtext
+14.5 13.9 moveto 51 (PFECAT) alignedtext
 grestore
-% NAGC05->ALIST
+% MRATFAC->PFECAT
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 35 72 moveto
-35 64 35 55 35 46 curveto
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 38.5001 46 moveto
-35 36 lineto
-31.5001 46 lineto
+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 38.5001 46 moveto
-35 36 lineto
-31.5001 46 lineto
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 114 152
+%%BoundingBox: 36 36 124 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104norminmonogenicalgebra.ps b/books/ps/v104norminmonogenicalgebra.ps
index d5172f0..59d823f 100644
--- a/books/ps/v104norminmonogenicalgebra.ps
+++ b/books/ps/v104norminmonogenicalgebra.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 130 152
+%%PageBoundingBox: 36 36 132 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 94 116 boxprim clip newpath
+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
@@ -200,72 +200,72 @@ newpath -4 -4 moveto
 closepath stroke
 % NORMMA
 gsave
-[ /Rect [ 3 72 83 108 ]
+[ /Rect [ 4 72 84 108 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=NORMMA) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 83 108 moveto
-3 108 lineto
-3 72 lineto
-83 72 lineto
+newpath 84 108 moveto
+4 108 lineto
+4 72 lineto
+84 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 83 108 moveto
-3 108 lineto
-3 72 lineto
-83 72 lineto
+newpath 84 108 moveto
+4 108 lineto
+4 72 lineto
+84 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-11 86.4 moveto 64 (NORMMA) alignedtext
+14.00 /Times-Roman set_font
+11.5 85.9 moveto 65 (NORMMA) alignedtext
 grestore
 % MONOGEN
 gsave
-[ /Rect [ 0 0 86 36 ]
+[ /Rect [ 0 0 88 36 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
   /Subtype /Link
 /ANN pdfmark
 0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
 closepath fill
 1 setlinewidth
 filled
 0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-8 14.4 moveto 70 (MONOGEN) alignedtext
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 73 (MONOGEN) alignedtext
 grestore
 % NORMMA->MONOGEN
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 43 72 moveto
-43 64 43 55 43 46 curveto
+newpath 44 72 moveto
+44 64 44 55 44 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+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 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+newpath 47.5001 46 moveto
+44 36 lineto
+40.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 130 152
+%%BoundingBox: 36 36 132 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104padeapproximantpackage.ps b/books/ps/v104padeapproximantpackage.ps
new file mode 100644
index 0000000..c31e863
--- /dev/null
+++ b/books/ps/v104padeapproximantpackage.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 120 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 84 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
+% PADEPAC
+gsave
+[ /Rect [ 0 72 76 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PADEPAC) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 76 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+76 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 76 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+76 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 60 (PADEPAC) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 5 0 71 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 71 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+71 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 71 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+71 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PADEPAC->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 38 72 moveto
+38 64 38 55 38 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 41.5001 46 moveto
+38 36 lineto
+34.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 41.5001 46 moveto
+38 36 lineto
+34.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 120 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104padeapproximants.ps b/books/ps/v104padeapproximants.ps
new file mode 100644
index 0000000..1a54271
--- /dev/null
+++ b/books/ps/v104padeapproximants.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
+% PADE
+gsave
+[ /Rect [ 8 72 62 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PADE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+8 108 lineto
+8 72 lineto
+62 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+8 108 lineto
+8 72 lineto
+62 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 85.9 moveto 35 (PADE) alignedtext
+grestore
+% UTSCAT
+gsave
+[ /Rect [ 0 0 70 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=UTSCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+2.13163e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+70 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+2.13163e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+70 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 54 (UTSCAT) alignedtext
+grestore
+% PADE->UTSCAT
+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/v104padicwildfunctionfieldintegralbasis.ps b/books/ps/v104padicwildfunctionfieldintegralbasis.ps
new file mode 100644
index 0000000..5670a49
--- /dev/null
+++ b/books/ps/v104padicwildfunctionfieldintegralbasis.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
+% PWFFINTB
+gsave
+[ /Rect [ 2 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PWFFINTB) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2 108 lineto
+2 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2 108 lineto
+2 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+10 85.9 moveto 68 (PWFFINTB) alignedtext
+grestore
+% MONOGEN
+gsave
+[ /Rect [ 0 0 88 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 88 36 moveto
+2.93238e-14 36 lineto
+8.24688e-15 1.06581e-14 lineto
+88 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 73 (MONOGEN) alignedtext
+grestore
+% PWFFINTB->MONOGEN
+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/v104parametriclinearequations.ps b/books/ps/v104parametriclinearequations.ps
new file mode 100644
index 0000000..d2e506c
--- /dev/null
+++ b/books/ps/v104parametriclinearequations.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
+% PLEQN
+gsave
+[ /Rect [ 3 72 63 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PLEQN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 63 108 moveto
+3 108 lineto
+3 72 lineto
+63 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 63 108 moveto
+3 108 lineto
+3 72 lineto
+63 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+10.5 85.9 moveto 45 (PLEQN) 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
+% PLEQN->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/v104parametricplanecurvefunctions2.ps b/books/ps/v104parametricplanecurvefunctions2.ps
new file mode 100644
index 0000000..a4b438b
--- /dev/null
+++ b/books/ps/v104parametricplanecurvefunctions2.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 108 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 72 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
+% PARPC2
+gsave
+[ /Rect [ 0 72 64 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PARPC2) >>
+  /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 (PARPC2) alignedtext
+grestore
+% TYPE
+gsave
+[ /Rect [ 5 0 59 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 59 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+59 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 59 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+59 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 35 (TYPE) alignedtext
+grestore
+% PARPC2->TYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 32 72 moveto
+32 64 32 55 32 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 35.5001 46 moveto
+32 36 lineto
+28.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 35.5001 46 moveto
+32 36 lineto
+28.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 108 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104parametricspacecurvefunctions2.ps b/books/ps/v104parametricspacecurvefunctions2.ps
new file mode 100644
index 0000000..e4b4763
--- /dev/null
+++ b/books/ps/v104parametricspacecurvefunctions2.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 108 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 72 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
+% PARSC2
+gsave
+[ /Rect [ 0 72 64 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PARSC2) >>
+  /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 (PARSC2) alignedtext
+grestore
+% TYPE
+gsave
+[ /Rect [ 5 0 59 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 59 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+59 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 59 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+59 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 35 (TYPE) alignedtext
+grestore
+% PARSC2->TYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 32 72 moveto
+32 64 32 55 32 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 35.5001 46 moveto
+32 36 lineto
+28.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 35.5001 46 moveto
+32 36 lineto
+28.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 108 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104parametricsurfacefunctions2.ps b/books/ps/v104parametricsurfacefunctions2.ps
new file mode 100644
index 0000000..dd72cd5
--- /dev/null
+++ b/books/ps/v104parametricsurfacefunctions2.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
+% PARSU2
+gsave
+[ /Rect [ 0 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PARSU2) >>
+  /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 (PARSU2) alignedtext
+grestore
+% TYPE
+gsave
+[ /Rect [ 6 0 60 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 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
+15.5 13.9 moveto 35 (TYPE) alignedtext
+grestore
+% PARSU2->TYPE
+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/v104partialfractionpackage.ps b/books/ps/v104partialfractionpackage.ps
new file mode 100644
index 0000000..940cabf
--- /dev/null
+++ b/books/ps/v104partialfractionpackage.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
+% PFRPAC
+gsave
+[ /Rect [ 0 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PFRPAC) >>
+  /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 (PFRPAC) 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
+% PFRPAC->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/v104partitionsandpermutations.ps b/books/ps/v104partitionsandpermutations.ps
new file mode 100644
index 0000000..d73fa99
--- /dev/null
+++ b/books/ps/v104partitionsandpermutations.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 130 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 94 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
+% PARTPERM
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PARTPERM) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 71 (PARTPERM) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 12 0 74 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 74 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+74 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 74 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+74 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PARTPERM->FLAGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 43 72 moveto
+43 64 43 55 43 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 130 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104patternfunctions1.ps b/books/ps/v104patternfunctions1.ps
new file mode 100644
index 0000000..c3a709a
--- /dev/null
+++ b/books/ps/v104patternfunctions1.ps
@@ -0,0 +1,371 @@
+%!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 284 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 248 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
+% PATTERN1
+gsave
+[ /Rect [ 91 72 173 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PATTERN1) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 173 108 moveto
+91 108 lineto
+91 72 lineto
+173 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 173 108 moveto
+91 108 lineto
+91 72 lineto
+173 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+98.5 85.9 moveto 67 (PATTERN1) alignedtext
+grestore
+% BASTYPE
+gsave
+[ /Rect [ 0 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=BASTYPE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-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.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 62 (BASTYPE) alignedtext
+grestore
+% PATTERN1->BASTYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 109 72 moveto
+98 63 83 52 70 42 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 72.1 39.2 moveto
+62 36 lineto
+67.9 44.8 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 72.1 39.2 moveto
+62 36 lineto
+67.9 44.8 lineto
+closepath stroke
+grestore
+% KOERCE
+gsave
+[ /Rect [ 96 0 168 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=KOERCE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+168 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+168 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+103.5 13.9 moveto 57 (KOERCE) alignedtext
+grestore
+% PATTERN1->KOERCE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 132 72 moveto
+132 64 132 55 132 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 135.5 46 moveto
+132 36 lineto
+128.5 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 135.5 46 moveto
+132 36 lineto
+128.5 46 lineto
+closepath stroke
+grestore
+% TYPE
+gsave
+[ /Rect [ 186 0 240 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 240 36 moveto
+186 36 lineto
+186 1.06581e-14 lineto
+240 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 240 36 moveto
+186 36 lineto
+186 1.06581e-14 lineto
+240 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+195.5 13.9 moveto 35 (TYPE) alignedtext
+grestore
+% PATTERN1->TYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 152 72 moveto
+162 63 174 52 185 43 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 187.779 45.2191 moveto
+193 36 lineto
+183.169 39.9511 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 187.779 45.2191 moveto
+193 36 lineto
+183.169 39.9511 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 284 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104patternfunctions2.ps b/books/ps/v104patternfunctions2.ps
new file mode 100644
index 0000000..a16b2e4
--- /dev/null
+++ b/books/ps/v104patternfunctions2.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
+% PATTERN2
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PATTERN2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 67 (PATTERN2) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 10 0 72 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 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PATTERN2->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/v104patternmatch.ps b/books/ps/v104patternmatch.ps
new file mode 100644
index 0000000..a68852c
--- /dev/null
+++ b/books/ps/v104patternmatch.ps
@@ -0,0 +1,416 @@
+%!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 404 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 368 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
+% PATMATCH
+gsave
+[ /Rect [ 134 72 222 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PATMATCH) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 222 108 moveto
+134 108 lineto
+134 72 lineto
+222 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 222 108 moveto
+134 108 lineto
+134 72 lineto
+222 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+141.5 85.9 moveto 73 (PATMATCH) alignedtext
+grestore
+% PATMAB
+gsave
+[ /Rect [ 0 0 70 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PATMAB) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+2.73566e-14 36 lineto
+6.33868e-15 1.06581e-14 lineto
+70 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 70 36 moveto
+2.73566e-14 36 lineto
+6.33868e-15 1.06581e-14 lineto
+70 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 55 (PATMAB) alignedtext
+grestore
+% PATMATCH->PATMAB
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 142 72 moveto
+123 62 99 51 79 41 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 80.4414 37.7969 moveto
+70 36 lineto
+77.0418 43.916 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 80.4414 37.7969 moveto
+70 36 lineto
+77.0418 43.916 lineto
+closepath stroke
+grestore
+% RETRACT
+gsave
+[ /Rect [ 88 0 168 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=RETRACT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+88 36 lineto
+88 1.06581e-14 lineto
+168 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+88 36 lineto
+88 1.06581e-14 lineto
+168 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+95.5 13.9 moveto 65 (RETRACT) alignedtext
+grestore
+% PATMATCH->RETRACT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 165 72 moveto
+160 64 153 54 147 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 149.8 41.9 moveto
+141 36 lineto
+144.2 46.1 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 149.8 41.9 moveto
+141 36 lineto
+144.2 46.1 lineto
+closepath stroke
+grestore
+% LMODULE
+gsave
+[ /Rect [ 186 0 270 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=LMODULE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 270 36 moveto
+186 36 lineto
+186 1.06581e-14 lineto
+270 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 270 36 moveto
+186 36 lineto
+186 1.06581e-14 lineto
+270 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+193.5 13.9 moveto 69 (LMODULE) alignedtext
+grestore
+% PATMATCH->LMODULE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 191 72 moveto
+196 64 203 54 209 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 211.8 46.1 moveto
+215 36 lineto
+206.2 41.9 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 211.8 46.1 moveto
+215 36 lineto
+206.2 41.9 lineto
+closepath stroke
+grestore
+% SGROUP
+gsave
+[ /Rect [ 288 0 360 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 360 36 moveto
+288 36 lineto
+288 1.06581e-14 lineto
+360 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 360 36 moveto
+288 36 lineto
+288 1.06581e-14 lineto
+360 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+296 13.9 moveto 56 (SGROUP) alignedtext
+grestore
+% PATMATCH->SGROUP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 215 72 moveto
+234 62 258 51 279 41 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 280.958 43.916 moveto
+288 36 lineto
+277.559 37.7969 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 280.958 43.916 moveto
+288 36 lineto
+277.559 37.7969 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 404 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104patternmatchfunctionspace.ps b/books/ps/v104patternmatchfunctionspace.ps
new file mode 100644
index 0000000..37aa3c3
--- /dev/null
+++ b/books/ps/v104patternmatchfunctionspace.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
+% PMFS
+gsave
+[ /Rect [ 0 72 54 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMFS) >>
+  /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.5 85.9 moveto 35 (PMFS) 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
+% PMFS->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/v104patternmatchintegernumbersystem.ps b/books/ps/v104patternmatchintegernumbersystem.ps
new file mode 100644
index 0000000..fb11431
--- /dev/null
+++ b/books/ps/v104patternmatchintegernumbersystem.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 192 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 156 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
+% PMINS
+gsave
+[ /Rect [ 43 72 101 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMINS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 101 108 moveto
+43 108 lineto
+43 72 lineto
+101 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 101 108 moveto
+43 108 lineto
+43 72 lineto
+101 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+51 85.9 moveto 42 (PMINS) 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
+% PMINS->FLAGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 62 72 moveto
+57 64 52 54 46 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 48.916 43.0418 moveto
+41 36 lineto
+42.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 48.916 43.0418 moveto
+41 36 lineto
+42.7969 46.4414 lineto
+closepath stroke
+grestore
+% FLAGG-
+gsave
+[ /Rect [ 80 0 148 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 148 36 moveto
+80 36 lineto
+80 1.06581e-14 lineto
+148 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 148 36 moveto
+80 36 lineto
+80 1.06581e-14 lineto
+148 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+88 13.9 moveto 52 (FLAGG-) alignedtext
+grestore
+% PMINS->FLAGG-
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 83 72 moveto
+88 64 93 54 99 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 102.203 46.4414 moveto
+104 36 lineto
+96.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 102.203 46.4414 moveto
+104 36 lineto
+96.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 192 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104patternmatchkernel.ps b/books/ps/v104patternmatchkernel.ps
new file mode 100644
index 0000000..0350587
--- /dev/null
+++ b/books/ps/v104patternmatchkernel.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
+% PMKERNEL
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMKERNEL) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+1.9304e-14 108 lineto
+-1.77636e-15 72 lineto
+90 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 90 108 moveto
+1.9304e-14 108 lineto
+-1.77636e-15 72 lineto
+90 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 75 (PMKERNEL) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 18 0 72 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 72 36 moveto
+18 36 lineto
+18 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 72 36 moveto
+18 36 lineto
+18 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+25.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% PMKERNEL->ALIST
+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/v104patternmatchlistaggregate.ps b/books/ps/v104patternmatchlistaggregate.ps
new file mode 100644
index 0000000..8551aac
--- /dev/null
+++ b/books/ps/v104patternmatchlistaggregate.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
+% PMLSAGG
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMLSAGG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 67 (PMLSAGG) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 10 0 72 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 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PMLSAGG->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/v104patternmatchpolynomialcategory.ps b/books/ps/v104patternmatchpolynomialcategory.ps
new file mode 100644
index 0000000..65dfc2b
--- /dev/null
+++ b/books/ps/v104patternmatchpolynomialcategory.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
+% PMPLCAT
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMPLCAT) >>
+  /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 (PMPLCAT) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 6 0 72 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 72 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PMPLCAT->PFECAT
+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/v104patternmatchpushdown.ps b/books/ps/v104patternmatchpushdown.ps
new file mode 100644
index 0000000..e659261
--- /dev/null
+++ b/books/ps/v104patternmatchpushdown.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
+% PMDOWN
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMDOWN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 64 (PMDOWN) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 9 0 71 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 71 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+71 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 71 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+71 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PMDOWN->FLAGG
+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/v104patternmatchquotientfieldcategory.ps b/books/ps/v104patternmatchquotientfieldcategory.ps
new file mode 100644
index 0000000..def2f17
--- /dev/null
+++ b/books/ps/v104patternmatchquotientfieldcategory.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
+% PMQFCAT
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMQFCAT) >>
+  /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 (PMQFCAT) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 7 0 73 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 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PMQFCAT->PFECAT
+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/v104patternmatchresultfunctions2.ps b/books/ps/v104patternmatchresultfunctions2.ps
new file mode 100644
index 0000000..f299ba7
--- /dev/null
+++ b/books/ps/v104patternmatchresultfunctions2.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 212 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 176 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
+% PATRES2
+gsave
+[ /Rect [ 49 72 121 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PATRES2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 121 108 moveto
+49 108 lineto
+49 72 lineto
+121 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 121 108 moveto
+49 108 lineto
+49 72 lineto
+121 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+57 85.9 moveto 56 (PATRES2) alignedtext
+grestore
+% BASTYPE
+gsave
+[ /Rect [ 0 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=BASTYPE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-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.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 62 (BASTYPE) alignedtext
+grestore
+% PATRES2->BASTYPE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 73 72 moveto
+68 64 61 54 55 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 58.268 42.625 moveto
+50 36 lineto
+52.332 46.335 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 58.268 42.625 moveto
+50 36 lineto
+52.332 46.335 lineto
+closepath stroke
+grestore
+% KOERCE
+gsave
+[ /Rect [ 96 0 168 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=KOERCE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+168 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 168 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+168 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+103.5 13.9 moveto 57 (KOERCE) alignedtext
+grestore
+% PATRES2->KOERCE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 97 72 moveto
+102 64 109 54 115 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 117.668 46.335 moveto
+120 36 lineto
+111.732 42.625 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 117.668 46.335 moveto
+120 36 lineto
+111.732 42.625 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 212 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104patternmatchsymbol.ps b/books/ps/v104patternmatchsymbol.ps
new file mode 100644
index 0000000..023b09e
--- /dev/null
+++ b/books/ps/v104patternmatchsymbol.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
+% PMSYM
+gsave
+[ /Rect [ 0 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMSYM) >>
+  /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 (PMSYM) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 6 0 60 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 60 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+60 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 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
+13.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% PMSYM->ALIST
+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/v104patternmatchtools.ps b/books/ps/v104patternmatchtools.ps
new file mode 100644
index 0000000..945b35c
--- /dev/null
+++ b/books/ps/v104patternmatchtools.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
+% PMTOOLS
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PMTOOLS) >>
+  /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 (PMTOOLS) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 10 0 72 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 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PMTOOLS->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/v104permanent.ps b/books/ps/v104permanent.ps
new file mode 100644
index 0000000..9b4c5d5
--- /dev/null
+++ b/books/ps/v104permanent.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
+% GRAY
+gsave
+[ /Rect [ 12 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=GRAY) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+12 108 lineto
+12 72 lineto
+66 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+12 108 lineto
+12 72 lineto
+66 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20 85.9 moveto 38 (GRAY) alignedtext
+grestore
+% IVECTOR
+gsave
+[ /Rect [ 0 0 78 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 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 62 (IVECTOR) alignedtext
+grestore
+% GRAY->IVECTOR
+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/v104permutationgroupexamples.ps b/books/ps/v104permutationgroupexamples.ps
new file mode 100644
index 0000000..b27494e
--- /dev/null
+++ b/books/ps/v104permutationgroupexamples.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
+% PGE
+gsave
+[ /Rect [ 4 72 58 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PGE) >>
+  /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
+17.5 85.9 moveto 27 (PGE) 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
+% PGE->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/v104plotfunctions1.ps b/books/ps/v104plotfunctions1.ps
new file mode 100644
index 0000000..887f61c
--- /dev/null
+++ b/books/ps/v104plotfunctions1.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
+% PLOT1
+gsave
+[ /Rect [ 12 72 70 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PLOT1) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+12 108 lineto
+12 72 lineto
+70 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+12 108 lineto
+12 72 lineto
+70 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20 85.9 moveto 42 (PLOT1) alignedtext
+grestore
+% KONVERT
+gsave
+[ /Rect [ 0 0 82 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=KONVERT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+82 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+2.84217e-14 36 lineto
+7.10543e-15 1.06581e-14 lineto
+82 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 66 (KONVERT) alignedtext
+grestore
+% PLOT1->KONVERT
+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/v104plottools.ps b/books/ps/v104plottools.ps
new file mode 100644
index 0000000..263574e
--- /dev/null
+++ b/books/ps/v104plottools.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 188 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 152 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
+% PLOTTOOL
+gsave
+[ /Rect [ 22 72 112 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PLOTTOOL) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 112 108 moveto
+22 108 lineto
+22 72 lineto
+112 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 112 108 moveto
+22 108 lineto
+22 72 lineto
+112 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+30 85.9 moveto 74 (PLOTTOOL) alignedtext
+grestore
+% FIELD
+gsave
+[ /Rect [ 0 0 54 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 54 36 moveto
+1.41189e-14 36 lineto
+3.65506e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 54 36 moveto
+1.41189e-14 36 lineto
+3.65506e-15 1.06581e-14 lineto
+54 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 39 (FIELD) alignedtext
+grestore
+% PLOTTOOL->FIELD
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 57 72 moveto
+53 64 47 54 42 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 44.916 43.0418 moveto
+37 36 lineto
+38.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 44.916 43.0418 moveto
+37 36 lineto
+38.7969 46.4414 lineto
+closepath stroke
+grestore
+% RADCAT
+gsave
+[ /Rect [ 72 0 144 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=RADCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 144 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+144 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 144 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+144 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+80 13.9 moveto 56 (RADCAT) alignedtext
+grestore
+% PLOTTOOL->RADCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 77 72 moveto
+82 64 87 54 93 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 96.2031 46.4414 moveto
+98 36 lineto
+90.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 96.2031 46.4414 moveto
+98 36 lineto
+90.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 188 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104pointsoffiniteorder.ps b/books/ps/v104pointsoffiniteorder.ps
new file mode 100644
index 0000000..7e3248c
--- /dev/null
+++ b/books/ps/v104pointsoffiniteorder.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 174 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 138 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
+% PFO
+gsave
+[ /Rect [ 37 72 91 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PFO) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 91 108 moveto
+37 108 lineto
+37 72 lineto
+91 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 91 108 moveto
+37 108 lineto
+37 72 lineto
+91 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+51 85.9 moveto 26 (PFO) 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
+% PFO->FS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 55 72 moveto
+51 64 46 54 41 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.916 43.0418 moveto
+36 36 lineto
+37.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.916 43.0418 moveto
+36 36 lineto
+37.7969 46.4414 lineto
+closepath stroke
+grestore
+% FFCAT
+gsave
+[ /Rect [ 72 0 130 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FFCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 130 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+130 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 130 36 moveto
+72 36 lineto
+72 1.06581e-14 lineto
+130 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+80 13.9 moveto 42 (FFCAT) alignedtext
+grestore
+% PFO->FFCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 73 72 moveto
+77 64 82 54 87 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 90.2031 46.4414 moveto
+92 36 lineto
+84.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 90.2031 46.4414 moveto
+92 36 lineto
+84.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 174 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104pointsoffiniteorderrational.ps b/books/ps/v104pointsoffiniteorderrational.ps
new file mode 100644
index 0000000..5c6e1c6
--- /dev/null
+++ b/books/ps/v104pointsoffiniteorderrational.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 102 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 66 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
+% PFOQ
+gsave
+[ /Rect [ 2 72 56 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PFOQ) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+2 108 lineto
+2 72 lineto
+56 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+2 108 lineto
+2 72 lineto
+56 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11 85.9 moveto 36 (PFOQ) alignedtext
+grestore
+% FFCAT
+gsave
+[ /Rect [ 0 0 58 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FFCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+58 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+58 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 42 (FFCAT) alignedtext
+grestore
+% PFOQ->FFCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 29 72 moveto
+29 64 29 55 29 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 102 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104pointsoffiniteordertools.ps b/books/ps/v104pointsoffiniteordertools.ps
new file mode 100644
index 0000000..18855b1
--- /dev/null
+++ b/books/ps/v104pointsoffiniteordertools.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 130 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 94 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
+% PFOTOOLS
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PFOTOOLS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 71 (PFOTOOLS) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 10 0 76 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 76 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+76 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 76 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+76 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PFOTOOLS->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 43 72 moveto
+43 64 43 55 43 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 130 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104poltopol.ps b/books/ps/v104poltopol.ps
new file mode 100644
index 0000000..ed3ecc8
--- /dev/null
+++ b/books/ps/v104poltopol.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 130 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 94 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
+% POLTOPOL
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=POLTOPOL) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 71 (POLTOPOL) alignedtext
+grestore
+% DIRPCAT
+gsave
+[ /Rect [ 6 0 80 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 80 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+80 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 80 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+80 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14 13.9 moveto 58 (DIRPCAT) alignedtext
+grestore
+% POLTOPOL->DIRPCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 43 72 moveto
+43 64 43 55 43 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 130 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104polygroebner.ps b/books/ps/v104polygroebner.ps
new file mode 100644
index 0000000..a366227
--- /dev/null
+++ b/books/ps/v104polygroebner.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 116 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 80 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
+% PGROEB
+gsave
+[ /Rect [ 0 72 72 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PGROEB) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 72 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+72 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 72 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+72 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 56 (PGROEB) alignedtext
+grestore
+% FLAGG
+gsave
+[ /Rect [ 5 0 67 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 67 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+67 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 67 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+67 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12.5 13.9 moveto 47 (FLAGG) alignedtext
+grestore
+% PGROEB->FLAGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 36 72 moveto
+36 64 36 55 36 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 39.5001 46 moveto
+36 36 lineto
+32.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 39.5001 46 moveto
+36 36 lineto
+32.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 116 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104polynomialcategorylifting.ps b/books/ps/v104polynomialcategorylifting.ps
new file mode 100644
index 0000000..539db1a
--- /dev/null
+++ b/books/ps/v104polynomialcategorylifting.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
+% POLYLIFT
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=POLYLIFT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 80 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+80 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 64 (POLYLIFT) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 7 0 73 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 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% POLYLIFT->PFECAT
+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/v104polynomialcomposition.ps b/books/ps/v104polynomialcomposition.ps
new file mode 100644
index 0000000..c4c72e0
--- /dev/null
+++ b/books/ps/v104polynomialcomposition.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
+% PCOMP
+gsave
+[ /Rect [ 1 72 65 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PCOMP) >>
+  /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
+9 85.9 moveto 48 (PCOMP) 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
+% PCOMP->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/v104polynomialdecomposition.ps b/books/ps/v104polynomialdecomposition.ps
new file mode 100644
index 0000000..a5af8b9
--- /dev/null
+++ b/books/ps/v104polynomialdecomposition.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
+% PDECOMP
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PDECOMP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 67 (PDECOMP) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 8 0 74 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 74 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+74 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 74 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+74 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+15.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PDECOMP->PFECAT
+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/v104polynomialfactorizationbyrecursion.ps b/books/ps/v104polynomialfactorizationbyrecursion.ps
new file mode 100644
index 0000000..a8f0a21
--- /dev/null
+++ b/books/ps/v104polynomialfactorizationbyrecursion.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
+% PFBR
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PFBR) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16.5 85.9 moveto 33 (PFBR) 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
+% PFBR->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/v104polynomialfactorizationbyrecursionunivariate.ps b/books/ps/v104polynomialfactorizationbyrecursionunivariate.ps
new file mode 100644
index 0000000..b27494e
--- /dev/null
+++ b/books/ps/v104polynomialfactorizationbyrecursionunivariate.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
+% PGE
+gsave
+[ /Rect [ 4 72 58 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PGE) >>
+  /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
+17.5 85.9 moveto 27 (PGE) 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
+% PGE->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/v104polynomialgcdpackage.ps b/books/ps/v104polynomialgcdpackage.ps
new file mode 100644
index 0000000..5603046
--- /dev/null
+++ b/books/ps/v104polynomialgcdpackage.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
+% PGCD
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PGCD) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14 85.9 moveto 38 (PGCD) 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
+% PGCD->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/v104polynomialinterpolation.ps b/books/ps/v104polynomialinterpolation.ps
new file mode 100644
index 0000000..d37a72e
--- /dev/null
+++ b/books/ps/v104polynomialinterpolation.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 116 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 80 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
+% PINTERP
+gsave
+[ /Rect [ 0 72 72 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PINTERP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 72 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+72 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 72 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+72 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 56 (PINTERP) alignedtext
+grestore
+% FIELD
+gsave
+[ /Rect [ 9 0 63 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 63 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+63 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 63 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+63 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16.5 13.9 moveto 39 (FIELD) alignedtext
+grestore
+% PINTERP->FIELD
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 36 72 moveto
+36 64 36 55 36 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 39.5001 46 moveto
+36 36 lineto
+32.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 39.5001 46 moveto
+36 36 lineto
+32.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 116 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104polynomialinterpolationalgorithms.ps b/books/ps/v104polynomialinterpolationalgorithms.ps
new file mode 100644
index 0000000..85ce2db
--- /dev/null
+++ b/books/ps/v104polynomialinterpolationalgorithms.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
+% PINTERPA
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PINTERPA) >>
+  /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 (PINTERPA) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 7 0 73 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 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+73 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% PINTERPA->PFECAT
+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/v104polynomialsquarefree.ps b/books/ps/v104polynomialsquarefree.ps
new file mode 100644
index 0000000..575023b
--- /dev/null
+++ b/books/ps/v104polynomialsquarefree.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
+% PSQFR
+gsave
+[ /Rect [ 4 72 62 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PSQFR) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+4 108 lineto
+4 72 lineto
+62 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+4 108 lineto
+4 72 lineto
+62 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12 85.9 moveto 42 (PSQFR) 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
+% PSQFR->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/v104polynomialtounivariatepolynomial.ps b/books/ps/v104polynomialtounivariatepolynomial.ps
new file mode 100644
index 0000000..d764248
--- /dev/null
+++ b/books/ps/v104polynomialtounivariatepolynomial.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
+% POLY2UP
+gsave
+[ /Rect [ 0 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=POLY2UP) >>
+  /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 (POLY2UP) 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
+% POLY2UP->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/v104primitiveelement.ps b/books/ps/v104primitiveelement.ps
new file mode 100644
index 0000000..943a99d
--- /dev/null
+++ b/books/ps/v104primitiveelement.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
+% PRIMELT
+gsave
+[ /Rect [ 0 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PRIMELT) >>
+  /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 (PRIMELT) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 10 0 64 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 64 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+64 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 64 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+64 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% PRIMELT->ALIST
+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/v104printpackage.ps b/books/ps/v104printpackage.ps
new file mode 100644
index 0000000..9077317
--- /dev/null
+++ b/books/ps/v104printpackage.ps
@@ -0,0 +1,276 @@
+%!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
+% PRINT
+gsave
+[ /Rect [ 5 72 61 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PRINT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 61 108 moveto
+5 108 lineto
+5 72 lineto
+61 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 61 108 moveto
+5 108 lineto
+5 72 lineto
+61 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13 85.9 moveto 40 (PRINT) alignedtext
+grestore
+% Package
+gsave
+0.939 0.733 1.000 nodecolor
+newpath 66 36 moveto
+2.13163e-14 36 lineto
+0 1.06581e-14 lineto
+66 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 66 36 moveto
+2.13163e-14 36 lineto
+0 1.06581e-14 lineto
+66 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 50 (Package) alignedtext
+grestore
+% PRINT->Package
+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/v104pseudolinearnormalform.ps b/books/ps/v104pseudolinearnormalform.ps
new file mode 100644
index 0000000..8b93c1b
--- /dev/null
+++ b/books/ps/v104pseudolinearnormalform.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
+% PSEUDLIN
+gsave
+[ /Rect [ 0 72 82 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PSEUDLIN) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 82 108 moveto
+2.96881e-14 108 lineto
+8.62851e-15 72 lineto
+82 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 67 (PSEUDLIN) alignedtext
+grestore
+% IVECTOR
+gsave
+[ /Rect [ 2 0 80 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 80 36 moveto
+2 36 lineto
+2 1.06581e-14 lineto
+80 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 80 36 moveto
+2 36 lineto
+2 1.06581e-14 lineto
+80 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+10 13.9 moveto 62 (IVECTOR) alignedtext
+grestore
+% PSEUDLIN->IVECTOR
+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/v104pseudoremaindersequence.ps b/books/ps/v104pseudoremaindersequence.ps
new file mode 100644
index 0000000..991edca
--- /dev/null
+++ b/books/ps/v104pseudoremaindersequence.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
+% PRS
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=PRS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+21 85.9 moveto 24 (PRS) 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
+% PRS->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/v104rationalfunctionfactor.ps b/books/ps/v104rationalfunctionfactor.ps
index 47ad1a8..fef6161 100644
--- a/books/ps/v104rationalfunctionfactor.ps
+++ b/books/ps/v104rationalfunctionfactor.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 110 152
+%%PageBoundingBox: 36 36 112 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 74 116 boxprim clip newpath
+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
@@ -200,72 +200,72 @@ newpath -4 -4 moveto
 closepath stroke
 % RFFACT
 gsave
-[ /Rect [ 0 72 66 108 ]
+[ /Rect [ 0 72 68 108 ]
   /Border [ 0 0 0 ]
   /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RFFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 66 108 moveto
-0 108 lineto
-0 72 lineto
-66 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 66 108 moveto
-0 108 lineto
-0 72 lineto
-66 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-7.5 86.4 moveto 51 (RFFACT) alignedtext
+14.00 /Times-Roman set_font
+8 85.9 moveto 52 (RFFACT) alignedtext
 grestore
 % ALIST
 gsave
-[ /Rect [ 6 0 60 36 ]
+[ /Rect [ 7 0 61 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 60 36 moveto
-6 36 lineto
-6 0 lineto
-60 0 lineto
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath fill
 1 setlinewidth
 filled
 0.273 0.733 1.000 nodecolor
-newpath 60 36 moveto
-6 36 lineto
-6 0 lineto
-60 0 lineto
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-14 14.4 moveto 38 (ALIST) alignedtext
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 39 (ALIST) alignedtext
 grestore
 % RFFACT->ALIST
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 33 72 moveto
-33 64 33 55 33 46 curveto
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 36.5 46 moveto
-33 36 lineto
-29.5 46 lineto
+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 36.5 46 moveto
-33 36 lineto
-29.5 46 lineto
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 110 152
+%%BoundingBox: 36 36 112 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104realsolvepackage.ps b/books/ps/v104realsolvepackage.ps
index e3e1782..fef6161 100644
--- a/books/ps/v104realsolvepackage.ps
+++ b/books/ps/v104realsolvepackage.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 130 152
+%%PageBoundingBox: 36 36 112 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 94 116 boxprim clip newpath
+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
@@ -198,74 +198,74 @@ newpath -4 -4 moveto
 536 716 lineto
 536 -4 lineto
 closepath stroke
-% REALSOLV
+% RFFACT
 gsave
-[ /Rect [ 0 72 86 108 ]
+[ /Rect [ 0 72 68 108 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=REALSOLV) >>
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RFFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 86 108 moveto
-0 108 lineto
-0 72 lineto
-86 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 86 108 moveto
-0 108 lineto
-0 72 lineto
-86 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-7.5 86.4 moveto 71 (REALSOLV) alignedtext
+14.00 /Times-Roman set_font
+8 85.9 moveto 52 (RFFACT) alignedtext
 grestore
-% PFECAT
+% ALIST
 gsave
-[ /Rect [ 10 0 76 36 ]
+[ /Rect [ 7 0 61 36 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PFECAT) >>
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
   /Subtype /Link
 /ANN pdfmark
-0.606 0.733 1.000 nodecolor
-newpath 76 36 moveto
-10 36 lineto
-10 0 lineto
-76 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath fill
 1 setlinewidth
 filled
-0.606 0.733 1.000 nodecolor
-newpath 76 36 moveto
-10 36 lineto
-10 0 lineto
-76 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-18 14.4 moveto 50 (PFECAT) alignedtext
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 39 (ALIST) alignedtext
 grestore
-% REALSOLV->PFECAT
+% RFFACT->ALIST
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 43 72 moveto
-43 64 43 55 43 46 curveto
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+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 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 130 152
+%%BoundingBox: 36 36 112 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104reduceddivisor.ps b/books/ps/v104reduceddivisor.ps
new file mode 100644
index 0000000..a92cc28
--- /dev/null
+++ b/books/ps/v104reduceddivisor.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 102 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 66 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
+% RDIV
+gsave
+[ /Rect [ 2 72 56 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RDIV) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+2 108 lineto
+2 72 lineto
+56 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 56 108 moveto
+2 108 lineto
+2 72 lineto
+56 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12.5 85.9 moveto 33 (RDIV) alignedtext
+grestore
+% FFCAT
+gsave
+[ /Rect [ 0 0 58 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FFCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+58 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+2.13163e-14 36 lineto
+3.55271e-15 1.06581e-14 lineto
+58 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 13.9 moveto 42 (FFCAT) alignedtext
+grestore
+% RDIV->FFCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 29 72 moveto
+29 64 29 55 29 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 32.5001 46 moveto
+29 36 lineto
+25.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 102 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104saerationalfunctionalgfactor.ps b/books/ps/v104saerationalfunctionalgfactor.ps
index 892bcf4..fef6161 100644
--- a/books/ps/v104saerationalfunctionalgfactor.ps
+++ b/books/ps/v104saerationalfunctionalgfactor.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 130 152
+%%PageBoundingBox: 36 36 112 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 94 116 boxprim clip newpath
+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
@@ -198,74 +198,74 @@ newpath -4 -4 moveto
 536 716 lineto
 536 -4 lineto
 closepath stroke
-% SAERFFC
+% RFFACT
 gsave
-[ /Rect [ 6 72 80 108 ]
+[ /Rect [ 0 72 68 108 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SAERFFC) >>
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RFFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 80 108 moveto
-6 108 lineto
-6 72 lineto
-80 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 80 108 moveto
-6 108 lineto
-6 72 lineto
-80 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-13.5 86.4 moveto 59 (SAERFFC) alignedtext
+14.00 /Times-Roman set_font
+8 85.9 moveto 52 (RFFACT) alignedtext
 grestore
-% MONOGEN
+% ALIST
 gsave
-[ /Rect [ 0 0 86 36 ]
+[ /Rect [ 7 0 61 36 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
   /Subtype /Link
 /ANN pdfmark
-0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath fill
 1 setlinewidth
 filled
-0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-8 14.4 moveto 70 (MONOGEN) alignedtext
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 39 (ALIST) alignedtext
 grestore
-% SAERFFC->MONOGEN
+% RFFACT->ALIST
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 43 72 moveto
-43 64 43 55 43 46 curveto
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+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 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 130 152
+%%BoundingBox: 36 36 112 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104simplealgebraicextensionalgfactor.ps b/books/ps/v104simplealgebraicextensionalgfactor.ps
index 95b7514..fef6161 100644
--- a/books/ps/v104simplealgebraicextensionalgfactor.ps
+++ b/books/ps/v104simplealgebraicextensionalgfactor.ps
@@ -1,5 +1,5 @@
 %!PS-Adobe-2.0
-%%Creator: Graphviz version 2.18 (Wed Aug  6 10:29:47 UTC 2008)
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
@@ -179,11 +179,11 @@ def
 %%EndSetup
 setupLatin1
 %%Page: 1 1
-%%PageBoundingBox: 36 36 130 152
+%%PageBoundingBox: 36 36 112 152
 %%PageOrientation: Portrait
 0 0 1 beginpage
 gsave
-36 36 94 116 boxprim clip newpath
+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
@@ -198,74 +198,74 @@ newpath -4 -4 moveto
 536 716 lineto
 536 -4 lineto
 closepath stroke
-% SAEFACT
+% RFFACT
 gsave
-[ /Rect [ 5 72 81 108 ]
+[ /Rect [ 0 72 68 108 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SAEFACT) >>
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=RFFACT) >>
   /Subtype /Link
 /ANN pdfmark
 0.939 0.733 1.000 nodecolor
-newpath 81 108 moveto
-5 108 lineto
-5 72 lineto
-81 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath fill
 1 setlinewidth
 filled
 0.939 0.733 1.000 nodecolor
-newpath 81 108 moveto
-5 108 lineto
-5 72 lineto
-81 72 lineto
+newpath 68 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+68 72 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-13 86.4 moveto 60 (SAEFACT) alignedtext
+14.00 /Times-Roman set_font
+8 85.9 moveto 52 (RFFACT) alignedtext
 grestore
-% MONOGEN
+% ALIST
 gsave
-[ /Rect [ 0 0 86 36 ]
+[ /Rect [ 7 0 61 36 ]
   /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
   /Subtype /Link
 /ANN pdfmark
-0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath fill
 1 setlinewidth
 filled
-0.606 0.733 1.000 nodecolor
-newpath 86 36 moveto
-0 36 lineto
-0 0 lineto
-86 0 lineto
+0.273 0.733 1.000 nodecolor
+newpath 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
 closepath stroke
 0.000 0.000 0.000 nodecolor
-14 /Times-Roman set_font
-8 14.4 moveto 70 (MONOGEN) alignedtext
+14.00 /Times-Roman set_font
+14.5 13.9 moveto 39 (ALIST) alignedtext
 grestore
-% SAEFACT->MONOGEN
+% RFFACT->ALIST
 gsave
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 43 72 moveto
-43 64 43 55 43 46 curveto
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
 stroke
 0.000 0.000 0.000 edgecolor
-newpath 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+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 46.5 46 moveto
-43 36 lineto
-39.5 46 lineto
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
 closepath stroke
 grestore
 endpage
@@ -275,7 +275,7 @@ grestore
 %%EndPage: 1
 %%Trailer
 %%Pages: 1
-%%BoundingBox: 36 36 130 152
+%%BoundingBox: 36 36 112 152
 end
 restore
 %%EOF
diff --git a/books/ps/v104sparseunivariatepolynomialfunctions2.ps b/books/ps/v104sparseunivariatepolynomialfunctions2.ps
new file mode 100644
index 0000000..14fc592
--- /dev/null
+++ b/books/ps/v104sparseunivariatepolynomialfunctions2.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 218 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 182 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
+% SUP2
+gsave
+[ /Rect [ 63 72 117 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SUP2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 117 108 moveto
+63 108 lineto
+63 72 lineto
+117 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 117 108 moveto
+63 108 lineto
+63 72 lineto
+117 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+74 85.9 moveto 32 (SUP2) alignedtext
+grestore
+% LMODULE
+gsave
+[ /Rect [ 0 0 84 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=LMODULE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+2.63123e-14 36 lineto
+5.2458e-15 1.06581e-14 lineto
+84 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+2.63123e-14 36 lineto
+5.2458e-15 1.06581e-14 lineto
+84 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 69 (LMODULE) alignedtext
+grestore
+% SUP2->LMODULE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 78 72 moveto
+73 64 66 54 60 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 62.8 41.9 moveto
+54 36 lineto
+57.2 46.1 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 62.8 41.9 moveto
+54 36 lineto
+57.2 46.1 lineto
+closepath stroke
+grestore
+% SGROUP
+gsave
+[ /Rect [ 102 0 174 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 174 36 moveto
+102 36 lineto
+102 1.06581e-14 lineto
+174 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 174 36 moveto
+102 36 lineto
+102 1.06581e-14 lineto
+174 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+110 13.9 moveto 56 (SGROUP) alignedtext
+grestore
+% SUP2->SGROUP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 102 72 moveto
+107 64 114 54 120 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 122.8 46.1 moveto
+126 36 lineto
+117.2 41.9 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 122.8 46.1 moveto
+126 36 lineto
+117.2 41.9 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 218 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104univariatepolynomialcategoryfunctions2.ps b/books/ps/v104univariatepolynomialcategoryfunctions2.ps
new file mode 100644
index 0000000..ad4bc8c
--- /dev/null
+++ b/books/ps/v104univariatepolynomialcategoryfunctions2.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
+% UPOLYC2
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UPOLYC2) >>
+  /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 (UPOLYC2) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 6 0 72 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 72 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+72 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 72 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+72 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% UPOLYC2->PFECAT
+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/v104univariatepolynomialfunctions2.ps b/books/ps/v104univariatepolynomialfunctions2.ps
new file mode 100644
index 0000000..cc75e55
--- /dev/null
+++ b/books/ps/v104univariatepolynomialfunctions2.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 218 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 182 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
+% UP2
+gsave
+[ /Rect [ 63 72 117 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UP2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 117 108 moveto
+63 108 lineto
+63 72 lineto
+117 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 117 108 moveto
+63 108 lineto
+63 72 lineto
+117 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+77.5 85.9 moveto 25 (UP2) alignedtext
+grestore
+% LMODULE
+gsave
+[ /Rect [ 0 0 84 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=LMODULE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+2.63123e-14 36 lineto
+5.2458e-15 1.06581e-14 lineto
+84 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 84 36 moveto
+2.63123e-14 36 lineto
+5.2458e-15 1.06581e-14 lineto
+84 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 69 (LMODULE) alignedtext
+grestore
+% UP2->LMODULE
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 78 72 moveto
+73 64 66 54 60 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 62.8 41.9 moveto
+54 36 lineto
+57.2 46.1 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 62.8 41.9 moveto
+54 36 lineto
+57.2 46.1 lineto
+closepath stroke
+grestore
+% SGROUP
+gsave
+[ /Rect [ 102 0 174 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 174 36 moveto
+102 36 lineto
+102 1.06581e-14 lineto
+174 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 174 36 moveto
+102 36 lineto
+102 1.06581e-14 lineto
+174 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+110 13.9 moveto 56 (SGROUP) alignedtext
+grestore
+% UP2->SGROUP
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 102 72 moveto
+107 64 114 54 120 44 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 122.8 46.1 moveto
+126 36 lineto
+117.2 41.9 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 122.8 46.1 moveto
+126 36 lineto
+117.2 41.9 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 218 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104univariatepolynomialmultiplicationpackage.ps b/books/ps/v104univariatepolynomialmultiplicationpackage.ps
new file mode 100644
index 0000000..d739cf6
--- /dev/null
+++ b/books/ps/v104univariatepolynomialmultiplicationpackage.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
+% UPMP
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UPMP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 60 108 moveto
+6 108 lineto
+6 72 lineto
+60 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14 85.9 moveto 38 (UPMP) 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
+% UPMP->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/v104univariatepolynomialsquarefree.ps b/books/ps/v104univariatepolynomialsquarefree.ps
new file mode 100644
index 0000000..4f55d49
--- /dev/null
+++ b/books/ps/v104univariatepolynomialsquarefree.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 130 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 94 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
+% UPSQFREE
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UPSQFREE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.7485e-14 108 lineto
+6.41154e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 71 (UPSQFREE) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 10 0 76 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 76 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+76 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 76 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+76 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% UPSQFREE->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 43 72 moveto
+43 64 43 55 43 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 46.5001 46 moveto
+43 36 lineto
+39.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 130 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104univariatepuiseuxseriesfunctions2.ps b/books/ps/v104univariatepuiseuxseriesfunctions2.ps
new file mode 100644
index 0000000..1206b5c
--- /dev/null
+++ b/books/ps/v104univariatepuiseuxseriesfunctions2.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
+% UPXS2
+gsave
+[ /Rect [ 41 72 99 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UPXS2) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 99 108 moveto
+41 108 lineto
+41 72 lineto
+99 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 99 108 moveto
+41 108 lineto
+41 72 lineto
+99 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+49 85.9 moveto 42 (UPXS2) 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
+% UPXS2->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
+% UPXS2->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/changelog b/changelog
index 6290590..f783eac 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,109 @@
+20090208 tpd src/axiom-website/patches.html 20090208.01.tpd.patch
+20090208 tpd books/bookvol10.4.pamphlet add packages
+20090208 tpd src/algebra/Makefile remove spad files
+20090208 tpd src/algebra/puiseux.spad removed
+20090208 tpd books/ps/v104univariatepuiseuxseriesfunctions2.ps added
+20090208 tpd src/algebra/pseudolin.spad removed
+20090208 tpd books/ps/v104pseudolinearnormalform.ps added
+20090208 tpd src/algebra/prs.spad removed
+20090208 tpd books/ps/v104pseudoremaindersequence.ps added
+20090208 tpd src/algebra/primelt.spad removed
+20090208 tpd books/ps/v104functionspaceprimitiveelement.ps added
+20090208 tpd books/ps/v104primitiveelement.ps added
+20090208 tpd src/algebra/poly.spad removed
+20090208 tpd books/ps/v104polynomialtounivariatepolynomial.ps added
+20090208 tpd books/ps/v104univariatepolynomialfunctions2.ps added
+20090208 tpd books/ps/v104univariatepolynomialmultiplicationpackage.ps added
+20090208 tpd books/ps/v104univariatepolynomialsquarefree.ps added
+20090208 tpd books/ps/v104polynomialsquarefree.ps added
+20090208 tpd books/ps/v104sparseunivariatepolynomialfunctions2.ps added
+20090208 tpd src/algebra/polycat.spad removed
+20090208 tpd books/ps/v104commuteunivariatepolynomialcategory.ps added
+20090208 tpd books/ps/v104univariatepolynomialcategoryfunctions2.ps added
+20090208 tpd books/ps/v104polynomialcategorylifting.ps added
+20090208 tpd src/algebra/print.spad removed
+20090208 tpd books/ps/v104printpackage.ps added
+20090208 tpd src/algebra/poltopol.spad removed
+20090208 tpd books/ps/v104poltopol.ps added
+20090208 tpd books/ps/v104mpolycatfunctions3.ps added
+20090208 tpd books/ps/v104mpolycatfunctions2.ps added
+20090208 tpd src/algebra/plottool.spad removed
+20090208 tpd books/ps/v104plottools.ps added
+20090208 tpd src/algebra/plot.spad removed
+20090208 tpd books/ps/v104plotfunctions1.ps added
+20090208 tpd src/algebra/pleqn.spad removed
+20090208 tpd books/ps/v104parametriclinearequations.ps added
+20090208 tpd src/algebra/pinterp.spad removed
+20090208 tpd books/ps/v104polynomialinterpolation.ps added
+20090208 tpd books/ps/v104polynomialinterpolationalgorithms.ps added
+20090208 tpd src/algebra/pgrobner.spad removed
+20090208 tpd books/ps/v104polygroebner.ps added
+20090208 tpd src/algebra/pgcd.spad removed
+20090208 tpd books/ps/v104polynomialgcdpackage.ps added
+20090208 tpd src/algebra/pfr.spad removed
+20090208 tpd books/ps/v104partialfractionpackage.ps added
+20090208 tpd src/algebra/pfo.spad removed
+20090208 tpd books/ps/v104pointsoffiniteorder.ps added
+20090208 tpd books/ps/v104functionspacereduce.ps added
+20090208 tpd books/ps/v104pointsoffiniteorderrational.ps added
+20090208 tpd books/ps/v104pointsoffiniteordertools.ps added
+20090208 tpd books/ps/v104reduceddivisor.ps added
+20090208 tpd books/ps/v104findorderfinite.ps added
+20090208 tpd src/algebra/pfbr.spad removed
+20090208 tpd books/ps/v104polynomialfactorizationbyrecursion.ps added
+20090208 tpd books/ps/v104polynomialfactorizationbyrecursionunivariate.ps
+20090208 tpd src/algebra/permgrps.spad removed
+20090208 tpd books/ps/v104permutationgroupexamples.ps added
+20090208 tpd src/algebra/perman.spad removed
+20090208 tpd books/ps/v104permanent.ps added
+20090208 tpd books/ps/v104graycode.ps added
+20090208 tpd src/algebra/pdecomp.spad removed
+20090208 tpd books/ps/v104polynomialdecomposition.ps added
+20090208 tpd books/ps/v104polynomialcomposition.ps added
+20090208 tpd src/algebra/pattern.spad removed
+20090208 tpd books/ps/v104patternfunctions2.ps added
+20090208 tpd books/ps/v104patternfunctions1.ps added
+20090208 tpd books/ps/v104simplealgebraicextensionalgfactor.ps added
+20090208 tpd books/ps/v104saerationalfunctionalgfactor.ps added
+20090208 tpd books/ps/v104realsolvepackage.ps added
+20090208 tpd books/ps/v104rationalfunctionfactor.ps added
+20090208 tpd books/ps/v104onedimensionalarrayfunctions2.ps added
+20090208 tpd books/ps/v104norminmonogenicalgebra.ps added
+20090208 tpd books/ps/v104nagseriessummationpackage.ps added
+20090208 tpd books/ps/v104nagrootfindingpackage.ps added
+20090208 tpd books/ps/v104nagpolynomialrootspackage.ps added
+20090208 tpd books/ps/v104mrationalfactorize.ps added
+20090208 tpd books/ps/v104inneralgfactor.ps added
+20090208 tpd books/ps/v104expertsystemcontinuitypackage1.ps added
+20090208 tpd books/ps/v104expertsystemcontinuitypackage.ps added
+20090208 tpd books/ps/v104algfactor.ps added
+20090208 tpd books/ps/v104algebraicfunction.ps added
+20090208 tpd src/algebra/patmatch2.spad removed
+20090208 tpd books/ps/v104patternmatch.ps added
+20090208 tpd books/ps/v104patternmatchfunctionspace.ps added
+20090208 tpd books/ps/v104patternmatchpolynomialcategory.ps added
+20090208 tpd books/ps/v104patternmatchquotientfieldcategory.ps added
+20090208 tpd books/ps/v104patternmatchintegernumbersystem.ps added
+20090208 tpd src/algebra/patmatch1.spad removed
+20090208 tpd books/ps/v104patternmatchlistaggregate.ps added
+20090208 tpd books/ps/v104patternmatchtools.ps added
+20090208 tpd books/ps/v104patternmatchpushdown.ps added
+20090208 tpd books/ps/v104patternmatchkernel.ps added
+20090208 tpd books/ps/v104patternmatchsymbol.ps added
+20090208 tpd books/ps/v104patternmatchresultfunctions2.ps added
+20090208 tpd src/algebra/partperm.spad removed
+20090208 tpd books/ps/v104partitionsandpermutations.ps added
+20090208 tpd src/algebra/paramete.spad removed
+20090208 tpd books/ps/v104parametricsurfacefunctions2.ps added
+20090208 tpd books/ps/v104parametricspacecurvefunctions2.ps added
+20090208 tpd books/ps/v104parametricplanecurvefunctions2.ps added
+20090208 tpd src/algebra/padiclib.spad removed
+20090208 tpd books/ps/v104padicwildfunctionfieldintegralbasis.ps added
+20090208 tpd books/ps/v104chineseremaindertoolsforintegralbases.ps added
+20090208 tpd books/ps/v104integralbasispolynomialtools.ps added
+20090208 tpd src/algebra/pade.spad removed
+20090208 tpd books/ps/v104padeapproximants.ps added
+20090208 tpd books/ps/v104padeapproximantpackage.ps added
 20090207 tpd src/axiom-website/patches.html 20090207.02.tpd.patch
 20090207 tpd books/bookvol10.4.pamphlet add packages
 20090207 tpd src/algebra/Makefile remove spad files
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index af382cc..607b64d 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -15771,18 +15771,6 @@ We need to figure out which mlift.spad to keep.
 <<environment>>=
 
 SPADFILES= \
- ${OUTSRC}/pade.spad ${OUTSRC}/padiclib.spad \
- ${OUTSRC}/paramete.spad ${OUTSRC}/partperm.spad ${OUTSRC}/patmatch1.spad \
- ${OUTSRC}/patmatch2.spad ${OUTSRC}/pattern.spad \
- ${OUTSRC}/pdecomp.spad ${OUTSRC}/perman.spad ${OUTSRC}/permgrps.spad \
- ${OUTSRC}/pfbr.spad ${OUTSRC}/pfo.spad \
- ${OUTSRC}/pfr.spad ${OUTSRC}/pgcd.spad \
- ${OUTSRC}/pgrobner.spad ${OUTSRC}/pinterp.spad ${OUTSRC}/pleqn.spad \
- ${OUTSRC}/plot.spad ${OUTSRC}/plottool.spad \
- ${OUTSRC}/poltopol.spad ${OUTSRC}/polycat.spad \
- ${OUTSRC}/poly.spad ${OUTSRC}/primelt.spad ${OUTSRC}/print.spad \
- ${OUTSRC}/prs.spad  \
- ${OUTSRC}/pseudolin.spad ${OUTSRC}/puiseux.spad \
  ${OUTSRC}/qalgset.spad ${OUTSRC}/quat.spad \
  ${OUTSRC}/radeigen.spad ${OUTSRC}/radix.spad ${OUTSRC}/random.spad \
  ${OUTSRC}/ratfact.spad ${OUTSRC}/rdeef.spad ${OUTSRC}/rderf.spad \
@@ -15847,18 +15835,6 @@ DOCFILES= \
  ${DOC}/nepip.as.dvi  \
  ${DOC}/noptip.as.dvi ${DOC}/nqip.as.dvi \
  ${DOC}/nrc.as.dvi  ${DOC}/nsfip.as.dvi \
- ${DOC}/pade.spad.dvi ${DOC}/padiclib.spad.dvi  \
- ${DOC}/paramete.spad.dvi ${DOC}/partperm.spad.dvi ${DOC}/patmatch1.spad.dvi \
- ${DOC}/patmatch2.spad.dvi ${DOC}/pattern.spad.dvi \
- ${DOC}/pdecomp.spad.dvi ${DOC}/perman.spad.dvi ${DOC}/permgrps.spad.dvi \
- ${DOC}/pfbr.spad.dvi ${DOC}/pfo.spad.dvi \
- ${DOC}/pfr.spad.dvi ${DOC}/pgcd.spad.dvi \
- ${DOC}/pgrobner.spad.dvi ${DOC}/pinterp.spad.dvi ${DOC}/pleqn.spad.dvi \
- ${DOC}/plot.spad.dvi ${DOC}/plottool.spad.dvi \
- ${DOC}/poltopol.spad.dvi ${DOC}/polycat.spad.dvi \
- ${DOC}/poly.spad.dvi ${DOC}/primelt.spad.dvi ${DOC}/print.spad.dvi \
- ${DOC}/prs.spad.dvi  \
- ${DOC}/pseudolin.spad.dvi ${DOC}/puiseux.spad.dvi \
  ${DOC}/qalgset.spad.dvi ${DOC}/quat.spad.dvi \
  ${DOC}/radeigen.spad.dvi ${DOC}/radix.spad.dvi ${DOC}/random.spad.dvi \
  ${DOC}/ratfact.spad.dvi ${DOC}/rdeef.spad.dvi ${DOC}/rderf.spad.dvi \
@@ -17316,12 +17292,12 @@ ${HELP}/PartialFraction.help: ${BOOKS}/bookvol10.3.pamphlet
             >${INPUT}/PartialFraction.input
 	@echo "PartialFraction (PFR)" >>${HELPFILE}
 
-${HELP}/Permanent.help: ${IN}/perman.spad.pamphlet
-	@echo 7062 create Permanent.help from ${IN}/perman.spad.pamphlet
-	@${TANGLE} -R"Permanent.help" ${IN}/perman.spad.pamphlet \
+${HELP}/Permanent.help: ${BOOKS}/bookvol10.4.pamphlet
+	@echo 7062 create Permanent.help from ${BOOKS}/bookvol10.4.pamphlet
+	@${TANGLE} -R"Permanent.help" ${BOOKS}/bookvol10.4.pamphlet \
            >${HELP}/Permanent.help
 	@cp ${HELP}/Permanent.help ${HELP}/PERMAN.help
-	@${TANGLE} -R"Permanent.input" ${IN}/perman.spad.pamphlet \
+	@${TANGLE} -R"Permanent.input" ${BOOKS}/bookvol10.4.pamphlet \
             >${INPUT}/Permanent.input
 	@echo "Permanent (PERMAN)" >>${HELPFILE}
 
diff --git a/src/algebra/pade.spad.pamphlet b/src/algebra/pade.spad.pamphlet
deleted file mode 100644
index de1a71b..0000000
--- a/src/algebra/pade.spad.pamphlet
+++ /dev/null
@@ -1,247 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pade.spad}
-\author{Barry Trager, William Burge, Martin Hassner,Stephen M. Watt}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PADEPAC PadeApproximantPackage}
-<<package PADEPAC PadeApproximantPackage>>=
-)abbrev package PADEPAC PadeApproximantPackage
-++ This package computes reliable Pad&ea. approximants using
-++ a generalized Viskovatov continued fraction algorithm.
-++ Authors: Trager,Burge, Hassner & Watt.
-++ Date Created: April 1987
-++ Date Last Updated: 12 April 1990
-++ Keywords: Pade, series
-++ Examples:
-++ References:
-++   "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
-
-PadeApproximantPackage(R: Field, x:Symbol, pt:R): Exports == Implementation where
-   PS ==> UnivariateTaylorSeries(R,x,pt)
-   UP ==> UnivariatePolynomial(x,R)
-   QF ==> Fraction UP
-   CF  ==> ContinuedFraction UP
-   NNI ==> NonNegativeInteger
-   Exports ==> with
-     pade:   (NNI,NNI,PS,PS) -> Union(QF,"failed")
-      ++ pade(nd,dd,ns,ds) computes the approximant as a quotient of polynomials
-      ++ (if it exists) for arguments
-      ++ nd (numerator degree of approximant),
-      ++ dd (denominator degree of approximant),
-      ++ ns (numerator series of function), and
-      ++ ds (denominator series of function).
-     pade:   (NNI,NNI,PS) -> Union(QF,"failed")
-      ++ pade(nd,dd,s)
-      ++ computes the quotient of polynomials
-      ++ (if it exists) with numerator degree at
-      ++ most nd and denominator degree at most dd
-      ++ which matches the series s to order \spad{nd + dd}.
-
-   Implementation ==> add
-     n,m : NNI
-     u,v : PS
-     pa := PadeApproximants(R,PS,UP)
-     pade(n,m,u,v) ==
-       ans:=pade(n,m,u,v)$pa
-       ans case "failed" => ans
-       pt = 0 => ans
-       num := numer(ans::QF)
-       den := denom(ans::QF)
-       xpt : UP := monomial(1,1)-monomial(pt,0)
-       num := num(xpt)
-       den := den(xpt)
-       num/den
-     pade(n,m,u) == pade(n,m,u,1)
-
-@
-\section{package PADE PadeApproximants}
-<<package PADE PadeApproximants>>=
-)abbrev package PADE PadeApproximants
-++ This package computes reliable Pad&ea. approximants using
-++ a generalized Viskovatov continued fraction algorithm.
-++ Authors: Burge, Hassner & Watt.
-++ Date Created: April 1987
-++ Date Last Updated: 12 April 1990
-++ Keywords: Pade, series
-++ Examples:
-++ References:
-++   "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
-PadeApproximants(R,PS,UP): Exports == Implementation where
-  R:  Field -- IntegralDomain
-  PS: UnivariateTaylorSeriesCategory R
-  UP: UnivariatePolynomialCategory R
- 
-  NNI ==> NonNegativeInteger
-  QF  ==> Fraction UP
-  CF  ==> ContinuedFraction UP
- 
-  Exports ==> with
-    pade:   (NNI,NNI,PS,PS) -> Union(QF,"failed")
-      ++ pade(nd,dd,ns,ds)
-      ++ computes the approximant as a quotient of polynomials
-      ++ (if it exists) for arguments
-      ++ nd (numerator degree of approximant),
-      ++ dd (denominator degree of approximant),
-      ++ ns (numerator series of function), and
-      ++ ds (denominator series of function).
-    padecf: (NNI,NNI,PS,PS) -> Union(CF, "failed")
-      ++ padecf(nd,dd,ns,ds)
-      ++ computes the approximant as a continued fraction of
-      ++ polynomials (if it exists) for arguments
-      ++ nd (numerator degree of approximant),
-      ++ dd (denominator degree of approximant),
-      ++ ns (numerator series of function), and
-      ++ ds (denominator series of function).
- 
-  Implementation ==> add
-    -- The approximant is represented as
-    --   p0 + x**a1/(p1 + x**a2/(...))
- 
-    PadeRep ==> Record(ais: List UP, degs: List NNI) -- #ais= #degs
-    PadeU   ==> Union(PadeRep, "failed")             -- #ais= #degs+1
- 
-    constInner(up:UP):PadeU == [[up], []]
- 
-    truncPoly(p:UP,n:NNI):UP ==
-      while n < degree p repeat p := reductum p
-      p
- 
-    truncSeries(s:PS,n:NNI):UP ==
-      p: UP := 0
-      for i in 0..n repeat p := p + monomial(coefficient(s,i),i)
-      p
- 
-    -- Assumes s starts with a<n>*x**n + ... and divides out x**n.
-    divOutDegree(s:PS,n:NNI):PS ==
-      for i in 1..n repeat s := quoByVar s
-      s
- 
-    padeNormalize: (NNI,NNI,PS,PS) -> PadeU
-    padeInner:     (NNI,NNI,PS,PS) -> PadeU
- 
-    pade(l,m,gps,dps) ==
-      (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
-      plist := ad.ais; dlist := ad.degs
-      approx := first(plist) :: QF
-      for d in dlist for p in rest plist repeat
-        approx := p::QF + (monomial(1,d)$UP :: QF)/approx
-      approx
- 
-    padecf(l,m,gps,dps) ==
-      (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
-      alist := reverse(ad.ais)
-      blist := [monomial(1,d)$UP for d in reverse ad.degs]
-      continuedFraction(first(alist),_
-                          blist::Stream UP,(rest alist) :: Stream UP)
- 
-    padeNormalize(l,m,gps,dps) ==
-      zero? dps => "failed"
-      zero? gps => constInner 0
-      -- Normalize so numerator or denominator has constant term.
-      ldeg:= min(order dps,order gps)
-      if ldeg > 0 then
-        dps := divOutDegree(dps,ldeg)
-        gps := divOutDegree(gps,ldeg)
-      padeInner(l,m,gps,dps)
- 
-    padeInner(l, m, gps, dps) ==
-      zero? coefficient(gps,0) and zero? coefficient(dps,0) =>
-        error "Pade' problem not normalized."
-      plist: List UP := nil()
-      alist: List NNI := nil()
-      -- Ensure denom has constant term.
-      if zero? coefficient(dps,0) then
-        -- g/d = 0 + z**0/(d/g)
-        (gps,dps) := (dps,gps)
-        (l,m)     := (m,l)
-        plist := concat(0,plist)
-        alist := concat(0,alist)
-      -- Ensure l >= m, maintaining coef(dps,0)^=0.
-      if l < m then
-        --   (a<n>*x**n + a<n+1>*x**n+1 + ...)/b
-        -- = x**n/b + (a<n> + a<n+1>*x + ...)/b
-        alpha := order gps
-        if alpha > l then return "failed"
-        gps := divOutDegree(gps, alpha)
-        (l,m) := (m,(l-alpha) :: NNI)
-        (gps,dps) := (dps,gps)
-        plist := concat(0,plist)
-        alist := concat(alpha,alist)
-      degbd: NNI := l + m + 1
-      g := truncSeries(gps,degbd)
-      d := truncSeries(dps,degbd)
-      for j in 0.. repeat
-        -- Normalize d so constant coefs cancel. (B&G-M is wrong)
-        d0 := coefficient(d,0)
-        d := (1/d0) * d; g := (1/d0) * g
-        p : UP := 0; s := g
-        if l-m+1 < 0 then error "Internal pade error"
-        degbd := (l-m+1) :: NNI
-        for k in 1..degbd repeat
-          pk := coefficient(s,0)
-          p  := p + monomial(pk,(k-1) :: NNI)
-          s  := s - pk*d
-          s  := (s exquo monomial(1,1)) :: UP
-        plist := concat(p,plist)
-        s = 0 => return [plist,alist]
-        alpha := minimumDegree(s) + degbd
-        alpha > l + m => return [plist,alist]
-        alpha > l     => return "failed"
-        alist := concat(alpha,alist)
-        h := (s exquo monomial(1,minimumDegree s)) :: UP
-        degbd := (l + m - alpha) :: NNI
-        g := truncPoly(d,degbd)
-        d := truncPoly(h,degbd)
-        (l,m) := (m,(l-alpha) :: NNI)
-
-@
-\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 PADEPAC PadeApproximantPackage>>
-<<package PADE PadeApproximants>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/padiclib.spad.pamphlet b/src/algebra/padiclib.spad.pamphlet
deleted file mode 100644
index 9b3e79c..0000000
--- a/src/algebra/padiclib.spad.pamphlet
+++ /dev/null
@@ -1,571 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra padiclib.spad}
-\author{Clifton J. Williamson}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package IBPTOOLS IntegralBasisPolynomialTools}
-<<package IBPTOOLS IntegralBasisPolynomialTools>>=
-)abbrev package IBPTOOLS IntegralBasisPolynomialTools
-++ Author: Clifton Williamson
-++ Date Created: 13 August 1993
-++ Date Last Updated: 17 August 1993
-++ Basic Operations: mapUnivariate, mapBivariate
-++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
-++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
-++ AMS Classifications:
-++ Keywords: function field, finite field, integral basis
-++ Examples:
-++ References:
-++ Description:  IntegralBasisPolynomialTools provides functions for
-++   mapping functions on the coefficients of univariate and bivariate
-++   polynomials.
-
-IntegralBasisPolynomialTools(K,R,UP,L): Exports == Implementation where
-  K  : Ring
-  R  : UnivariatePolynomialCategory K
-  UP : UnivariatePolynomialCategory R
-  L  : Ring
-
-  MAT ==> Matrix
-  SUP ==> SparseUnivariatePolynomial
-
-  Exports ==> with
-    mapUnivariate: (L -> K,SUP L) -> R
-      ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
-      ++ coefficients of \spad{p(x)}.
-
-    mapUnivariate: (K -> L,R) -> SUP L
-      ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
-      ++ coefficients of \spad{p(x)}.
-
-    mapUnivariateIfCan: (L -> Union(K,"failed"),SUP L) -> Union(R,"failed")
-      ++ mapUnivariateIfCan(f,p(x)) applies the function \spad{f} to the
-      ++ coefficients of \spad{p(x)}, if possible, and returns
-      ++ \spad{"failed"} otherwise.
-
-    mapMatrixIfCan: (L -> Union(K,"failed"),MAT SUP L) -> Union(MAT R,"failed")
-      ++ mapMatrixIfCan(f,mat) applies the function \spad{f} to the
-      ++ coefficients of the entries of \spad{mat} if possible, and returns
-      ++ \spad{"failed"} otherwise.
-
-    mapBivariate: (K -> L,UP) -> SUP SUP L
-      ++ mapBivariate(f,p(x,y)) applies the function \spad{f} to the
-      ++ coefficients of \spad{p(x,y)}.
-
-  Implementation ==> add
-
-    mapUnivariate(f:L -> K,poly:SUP L) ==
-      ans : R := 0
-      while not zero? poly repeat
-        ans := ans + monomial(f leadingCoefficient poly,degree poly)
-        poly := reductum poly
-      ans
-
-    mapUnivariate(f:K -> L,poly:R) ==
-      ans : SUP L := 0
-      while not zero? poly repeat
-        ans := ans + monomial(f leadingCoefficient poly,degree poly)
-        poly := reductum poly
-      ans
-
-    mapUnivariateIfCan(f,poly) ==
-      ans : R := 0
-      while not zero? poly repeat
-        (lc := f leadingCoefficient poly) case "failed" => return "failed"
-        ans := ans + monomial(lc :: K,degree poly)
-        poly := reductum poly
-      ans
-
-    mapMatrixIfCan(f,mat) ==
-      m := nrows mat; n := ncols mat
-      matOut : MAT R := new(m,n,0)
-      for i in 1..m repeat for j in 1..n repeat
-        (poly := mapUnivariateIfCan(f,qelt(mat,i,j))) case "failed" =>
-          return "failed"
-        qsetelt_!(matOut,i,j,poly :: R)
-      matOut
-
-    mapBivariate(f,poly) ==
-      ans : SUP SUP L := 0
-      while not zero? poly repeat
-        ans :=
-          ans + monomial(mapUnivariate(f,leadingCoefficient poly),degree poly)
-        poly := reductum poly
-      ans
-
-@
-\section{package IBACHIN ChineseRemainderToolsForIntegralBases}
-<<package IBACHIN ChineseRemainderToolsForIntegralBases>>=
-)abbrev package IBACHIN ChineseRemainderToolsForIntegralBases
-++ Author: Clifton Williamson
-++ Date Created: 9 August 1993
-++ Date Last Updated: 3 December 1993
-++ Basic Operations: chineseRemainder, factorList
-++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
-++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
-++ AMS Classifications:
-++ Keywords: function field, finite field, integral basis
-++ Examples:
-++ References:
-++ Description:
-
-ChineseRemainderToolsForIntegralBases(K,R,UP): Exports == Implementation where
-  K  : FiniteFieldCategory
-  R  : UnivariatePolynomialCategory K
-  UP : UnivariatePolynomialCategory R
-
-  DDFACT ==> DistinctDegreeFactorize
-  I      ==> Integer
-  L      ==> List
-  L2     ==> ListFunctions2
-  Mat    ==> Matrix R
-  NNI    ==> NonNegativeInteger
-  PI     ==> PositiveInteger
-  Q      ==> Fraction R
-  SAE    ==> SimpleAlgebraicExtension
-  SUP    ==> SparseUnivariatePolynomial
-  SUP2   ==> SparseUnivariatePolynomialFunctions2
-  Result ==> Record(basis: Mat, basisDen: R, basisInv: Mat)
-
-  Exports ==> with
-    factorList: (K,NNI,NNI,NNI) -> L SUP K
-	++ factorList(k,n,m,j) \undocumented
-
-    listConjugateBases: (Result,NNI,NNI) -> List Result
-      ++ listConjugateBases(bas,q,n) returns the list
-      ++ \spad{[bas,bas^Frob,bas^(Frob^2),...bas^(Frob^(n-1))]}, where
-      ++ \spad{Frob} raises the coefficients of all polynomials
-      ++ appearing in the basis \spad{bas} to the \spad{q}th power.
-
-    chineseRemainder: (List UP, List Result, NNI) -> Result
-	++ chineseRemainder(lu,lr,n) \undocumented
-
-  Implementation ==> add
-    import ModularHermitianRowReduction(R)
-    import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
-
-    applyFrobToMatrix: (Matrix R,NNI) -> Matrix R
-    applyFrobToMatrix(mat,q) ==
-      -- raises the coefficients of the polynomial entries of 'mat'
-      -- to the qth power
-      m := nrows mat; n := ncols mat
-      ans : Matrix R := new(m,n,0)
-      for i in 1..m repeat for j in 1..n repeat
-        qsetelt_!(ans,i,j,map(#1 ** q,qelt(mat,i,j)))
-      ans
-
-    listConjugateBases(bas,q,n) ==
-      outList : List Result := list bas
-      b := bas.basis; bInv := bas.basisInv; bDen := bas.basisDen
-      for i in 1..(n-1) repeat
-        b := applyFrobToMatrix(b,q)
-        bInv := applyFrobToMatrix(bInv,q)
-        bDen := map(#1 ** q,bDen)
-        newBasis : Result := [b,bDen,bInv]
-        outList := concat(newBasis,outList)
-      reverse_! outList
-
-    factorList(a,q,n,k) ==
-      coef : SUP K := monomial(a,0); xx : SUP K := monomial(1,1)
-      outList : L SUP K := list((xx - coef)**k)
-      for i in 1..(n-1) repeat
-        coef := coef ** q
-        outList := concat((xx - coef)**k,outList)
-      reverse_! outList
-
-    basisInfoToPolys: (Mat,R,R) -> L UP
-    basisInfoToPolys(mat,lcm,den) ==
-      n := nrows(mat) :: I; n1 := n - 1
-      outList : L UP := empty()
-      for i in 1..n repeat
-        pp : UP := 0
-        for j in 0..n1 repeat
-          pp := pp + monomial((lcm quo den) * qelt(mat,i,j+1),j)
-        outList := concat(pp,outList)
-      reverse_! outList
-
-    basesToPolyLists: (L Result,R) -> L L UP
-    basesToPolyLists(basisList,lcm) ==
-      [basisInfoToPolys(b.basis,lcm,b.basisDen) for b in basisList]
-
-    OUT ==> OutputForm
-
-    approximateExtendedEuclidean: (UP,UP,R,NNI) -> Record(coef1:UP,coef2:UP)
-    approximateExtendedEuclidean(f,g,p,n) ==
-      -- f and g are monic and relatively prime (mod p)
-      -- function returns [coef1,coef2] such that
-      -- coef1 * f + coef2 * g = 1 (mod p^n)
-      sae := SAE(K,R,p)
-      fSUP : SUP R := makeSUP f; gSUP : SUP R := makeSUP g
-      fBar : SUP sae := map(convert(#1)@sae,fSUP)$SUP2(R,sae)
-      gBar : SUP sae := map(convert(#1)@sae,gSUP)$SUP2(R,sae)
-      ee := extendedEuclidean(fBar,gBar)
---      not one?(ee.generator) =>
-      not (ee.generator = 1) =>
-        error "polynomials aren't relatively prime"
-      ss1 := ee.coef1; tt1 := ee.coef2
-      s1 : SUP R := map(convert(#1)@R,ss1)$SUP2(sae,R); s := s1
-      t1 : SUP R := map(convert(#1)@R,tt1)$SUP2(sae,R); t := t1
-      pPower := p
-      for i in 2..n repeat
-        num := 1 - s * fSUP - t * gSUP
-        rhs := (num exquo pPower) :: SUP R
-        sigma := map(#1 rem p,s1 * rhs); tau := map(#1 rem p,t1 * rhs)
-        s := s + pPower * sigma; t := t + pPower * tau
-        quorem := monicDivide(s,gSUP)
-        pPower := pPower * p
-        s := map(#1 rem pPower,quorem.remainder)
-        t := map(#1 rem pPower,t + fSUP * (quorem.quotient))
-      [unmakeSUP s,unmakeSUP t]
-
-    --mapChineseToList: (L SUP Q,L SUP Q,I) -> L SUP Q
-    --mapChineseToList(list,polyList,i) ==
-    mapChineseToList: (L UP,L UP,I,R) -> L UP
-    mapChineseToList(list,polyList,i,den) ==
-      -- 'polyList' consists of MONIC polynomials
-      -- computes a polynomial p such that p = pp (modulo polyList[i])
-      -- and p = 0 (modulo polyList[j]) for j ~= i for each 'pp' in 'list'
-      -- create polynomials
-      q : UP := 1
-      for j in 1..(i-1) repeat
-        q := q * first polyList
-        polyList := rest polyList
-      p := first polyList
-      polyList := rest polyList
-      for j in (i+1).. while not empty? polyList repeat
-        q := q * first polyList
-        polyList := rest polyList
-      --p := map((numer(#1) rem den)/1, p)
-      --q := map((numer(#1) rem den)/1, q)
-      -- 'den' is a power of an irreducible polynomial
-      --!! make this computation more efficient!!
-      factoredDen := factor(den)$DDFACT(K,R)
-      prime := nthFactor(factoredDen,1)
-      n := nthExponent(factoredDen,1) :: NNI
-      invPoly := approximateExtendedEuclidean(q,p,prime,n).coef1
-      -- monicDivide may be inefficient?
-      [monicDivide(pp * invPoly * q,p * q).remainder for pp in list]
-
-    polyListToMatrix: (L UP,NNI) -> Mat
-    polyListToMatrix(polyList,n) ==
-      mat : Mat := new(n,n,0)
-      for i in 1..n for poly in polyList repeat
-        while not zero? poly repeat
-          mat(i,degree(poly) + 1) := leadingCoefficient poly
-          poly := reductum poly
-      mat
-
-    chineseRemainder(factors,factorBases,n) ==
-      denLCM : R := reduce("lcm",[base.basisDen for base in factorBases])
-      denLCM = 1 => [scalarMatrix(n,1),1,scalarMatrix(n,1)]
-      -- compute local basis polynomials with denominators cleared
-      factorBasisPolyLists := basesToPolyLists(factorBases,denLCM)
-      -- use Chinese remainder to compute basis polynomials w/o denominators
-      basisPolyLists : L L UP := empty()
-      for i in 1.. for pList in factorBasisPolyLists repeat
-        polyList := mapChineseToList(pList,factors,i,denLCM)
-        basisPolyLists := concat(polyList,basisPolyLists)
-      basisPolys := concat reverse_! basisPolyLists
-      mat := squareTop rowEchelon(polyListToMatrix(basisPolys,n),denLCM)
-      matInv := UpTriBddDenomInv(mat,denLCM)
-      [mat,denLCM,matInv]
-
-@
-\section{package PWFFINTB PAdicWildFunctionFieldIntegralBasis}
-<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>=
-)abbrev package PWFFINTB PAdicWildFunctionFieldIntegralBasis
-++ Author: Clifton Williamson
-++ Date Created: 5 July 1993
-++ Date Last Updated: 17 August 1993
-++ Basic Operations: integralBasis, localIntegralBasis
-++ Related Domains: WildFunctionFieldIntegralBasis(K,R,UP,F)
-++ Also See: FunctionFieldIntegralBasis
-++ AMS Classifications:
-++ Keywords: function field, finite field, integral basis
-++ Examples:
-++ References:
-++ Description:
-++ In this package K is a finite field, R is a ring of univariate
-++ polynomials over K, and F is a monogenic algebra over R.
-++ We require that F is monogenic, i.e. that \spad{F = K[x,y]/(f(x,y))},
-++ because the integral basis algorithm used will factor the polynomial
-++ \spad{f(x,y)}.  The package provides a function to compute the integral
-++ closure of R in the quotient field of F as well as a function to compute
-++ a "local integral basis" at a specific prime.
-
-PAdicWildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
-  K  : FiniteFieldCategory
-  R  : UnivariatePolynomialCategory K
-  UP : UnivariatePolynomialCategory R
-  F  : MonogenicAlgebra(R,UP)
-
-  I        ==> Integer
-  L        ==> List
-  L2       ==> ListFunctions2
-  Mat      ==> Matrix R
-  NNI      ==> NonNegativeInteger
-  PI       ==> PositiveInteger
-  Q        ==> Fraction R
-  SAE      ==> SimpleAlgebraicExtension
-  SUP      ==> SparseUnivariatePolynomial
-  CDEN     ==> CommonDenominator
-  DDFACT   ==> DistinctDegreeFactorize
-  WFFINTBS ==> WildFunctionFieldIntegralBasis
-  Result   ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
-  IResult  ==> Record(basis: Mat, basisDen: R, basisInv:Mat,discr: R)
-  IBPTOOLS ==> IntegralBasisPolynomialTools
-  IBACHIN  ==> ChineseRemainderToolsForIntegralBases
-  IRREDFFX ==> IrredPolyOverFiniteField
-  GHEN     ==> GeneralHenselPackage
-
-  Exports ==> with
-    integralBasis : () -> Result
-      ++ \spad{integralBasis()} returns a record
-      ++ \spad{[basis,basisDen,basisInv] } containing information regarding
-      ++ the integral closure of R in the quotient field of the framed
-      ++ algebra F.  F is a framed algebra with R-module basis
-      ++ \spad{w1,w2,...,wn}.
-      ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
-      ++ the \spad{i}th element of the integral basis is
-      ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
-      ++ \spad{i}th row of 'basis' contains the coordinates of the
-      ++ \spad{i}th basis vector.  Similarly, the \spad{i}th row of the
-      ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
-      ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
-      ++ \spad{(bij, i = 1..n, j = 1..n)}, then
-      ++ \spad{wi = sum(bij * vj, j = 1..n)}.
-    localIntegralBasis : R -> Result
-      ++ \spad{integralBasis(p)} returns a record
-      ++ \spad{[basis,basisDen,basisInv] } containing information regarding
-      ++ the local integral closure of R at the prime \spad{p} in the quotient
-      ++ field of the framed algebra F.  F is a framed algebra with R-module
-      ++ basis \spad{w1,w2,...,wn}.
-      ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
-      ++ the \spad{i}th element of the local integral basis is
-      ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
-      ++ \spad{i}th row of 'basis' contains the coordinates of the
-      ++ \spad{i}th basis vector.  Similarly, the \spad{i}th row of the
-      ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
-      ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
-      ++ \spad{(bij, i = 1..n, j = 1..n)}, then
-      ++ \spad{wi = sum(bij * vj, j = 1..n)}.
-    reducedDiscriminant: UP -> R
-	++ reducedDiscriminant(up) \undocumented
-
-  Implementation ==> add
-    import IntegralBasisTools(R, UP, F)
-    import GeneralHenselPackage(R,UP)
-    import ModularHermitianRowReduction(R)
-    import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
-
-    reducedDiscriminant f ==
-      ff : SUP Q := mapUnivariate(#1 :: Q,f)$IBPTOOLS(R,UP,SUP UP,Q)
-      ee := extendedEuclidean(ff,differentiate ff)
-      cc := concat(coefficients(ee.coef1),coefficients(ee.coef2))
-      cden := splitDenominator(cc)$CDEN(R,Q,L Q)
-      denom := cden.den
-      gg := gcd map(numer,cden.num)$L2(Q,R)
-      (ans := denom exquo gg) case "failed" =>
-        error "PWFFINTB: error in reduced discriminant computation"
-      ans :: R
-
-    compLocalBasis: (UP,R) -> Result
-    compLocalBasis(poly,prime) ==
-      -- compute a local integral basis at 'prime' for k[x,y]/(poly(x,y)).
-      sae := SAE(R,UP,poly)
-      localIntegralBasis(prime)$WFFINTBS(K,R,UP,sae)
-
-    compLocalBasisOverExt: (UP,R,UP,NNI) -> Result
-    compLocalBasisOverExt(poly0,prime0,irrPoly0,k) ==
-      -- poly0 = irrPoly0**k (mod prime0)
-      n := degree poly0; disc0 := discriminant poly0
-      (disc0 exquo prime0) case "failed" =>
-        [scalarMatrix(n,1), 1, scalarMatrix(n,1)]
-      r := degree irrPoly0
-      -- extend scalars:
-      -- construct irreducible polynomial of degree r over K
-      irrPoly := generateIrredPoly(r :: PI)$IRREDFFX(K)
-      -- construct extension of degree r over K
-      E := SAE(K,SUP K,irrPoly)
-      -- lift coefficients to elements of E
-      poly := mapBivariate(#1 :: E,poly0)$IBPTOOLS(K,R,UP,E)
-      redDisc0 := reducedDiscriminant poly0
-      redDisc := mapUnivariate(#1 :: E,redDisc0)$IBPTOOLS(K,R,UP,E)
-      prime := mapUnivariate(#1 :: E,prime0)$IBPTOOLS(K,R,UP,E)
-      sae := SAE(E,SUP E,prime)
-      -- reduction (mod prime) of polynomial of which poly is the kth power
-      redIrrPoly :=
-        pp := mapBivariate(#1 :: E,irrPoly0)$IBPTOOLS(K,R,UP,E)
-        mapUnivariate(reduce,pp)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae)
-      -- factor the reduction
-      factorListSAE := factors factor(redIrrPoly)$DDFACT(sae,SUP sae)
-      -- list the 'primary factors' of the reduction of poly
-      redFactors : List SUP sae := [(f.factor)**k for f in factorListSAE]
-      -- lift these factors to elements of SUP SUP E
-      primaries : List SUP SUP E :=
-        [mapUnivariate(lift,ff)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae) _
-             for ff in redFactors]
-      -- lift the factors to factors modulo a suitable power of 'prime'
-      deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
-      henselInfo := HenselLift(poly,primaries,prime,deg)$GHEN(SUP E,SUP SUP E)
-      henselFactors := henselInfo.plist
-      psi1 := first henselFactors
-      FF := SAE(SUP E,SUP SUP E,psi1)
-      factorIb := localIntegralBasis(prime)$WFFINTBS(E,SUP E,SUP SUP E,FF)
-      bs := listConjugateBases(factorIb,size()$K,r)$IBACHIN(E,SUP E,SUP SUP E)
-      ib := chineseRemainder(henselFactors,bs,n)$IBACHIN(E,SUP E,SUP SUP E)
-      b : Matrix R :=
-        bas := mapMatrixIfCan(retractIfCan,ib.basis)$IBPTOOLS(K,R,UP,E)
-        bas case "failed" => error "retraction of basis failed"
-        bas :: Matrix R
-      bInv : Matrix R :=
-        --bas := mapMatrixIfCan(ric,ib.basisInv)$IBPTOOLS(K,R,UP,E)
-        bas := mapMatrixIfCan(retractIfCan,ib.basisInv)$IBPTOOLS(K,R,UP,E)
-        bas case "failed" => error "retraction of basis inverse failed"
-        bas :: Matrix R
-      bDen : R :=
-        p := mapUnivariateIfCan(retractIfCan,ib.basisDen)$IBPTOOLS(K,R,UP,E)
-        p case "failed" => error "retraction of basis denominator failed"
-        p :: R
-      [b,bDen,bInv]
-
-    padicLocalIntegralBasis: (UP,R,R,R) -> IResult
-    padicLocalIntegralBasis(p,disc,redDisc,prime) ==
-      -- polynomials in x modulo 'prime'
-      sae := SAE(K,R,prime)
-      -- find the factorization of 'p' modulo 'prime' and lift the
-      -- prime powers to elements of UP:
-      -- reduce 'p' modulo 'prime'
-      reducedP := mapUnivariate(reduce,p)$IBPTOOLS(R,UP,SUP UP,sae)
-      -- factor the reduced polynomial
-      factorListSAE := factors factor(reducedP)$DDFACT(sae,SUP sae)
-      -- if only one prime factor, perform usual integral basis computation
-      (# factorListSAE) = 1 =>
-        ib := localIntegralBasis(prime)$WFFINTBS(K,R,UP,F)
-        index := diagonalProduct(ib.basisInv)
-        [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
-      -- list the 'prime factors' of the reduced polynomial
-      redPrimes : List SUP sae :=
-        [f.factor for f in factorListSAE]
-      -- lift these factors to elements of UP
-      primes : List UP :=
-        [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimes]
-      -- list the exponents
-      expons : List NNI := [((f.exponent) :: NNI) for f in factorListSAE]
-      -- list the 'primary factors' of the reduced polynomial
-      redPrimaries : List SUP sae :=
-        [(f.factor) **((f.exponent) :: NNI) for f in factorListSAE]
-      -- lift these factors to elements of UP
-      primaries : List UP :=
-        [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimaries]
-      -- lift the factors to factors modulo a suitable power of 'prime'
-      deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
-      henselInfo := HenselLift(p,primaries,prime,deg)
-      henselFactors := henselInfo.plist
-      -- compute integral bases for the factors
-      factorBases : List Result := empty(); degPrime := degree prime
-      for pp in primes for k in expons for qq in henselFactors repeat
-        base :=
-          degPp := degree pp
-          degPp > 1 and gcd(degPp,degPrime) = 1 =>
-            compLocalBasisOverExt(qq,prime,pp,k)
-          compLocalBasis(qq,prime)
-        factorBases := concat(base,factorBases)
-      factorBases := reverse_! factorBases
-      ib := chineseRemainder(henselFactors,factorBases,rank()$F)$IBACHIN(K,R,UP)
-      index := diagonalProduct(ib.basisInv)
-      [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
-
-    localIntegralBasis prime ==
-      p := definingPolynomial()$F; disc := discriminant p
-      --disc := determinant traceMatrix()$F
-      redDisc := reducedDiscriminant p
-      ib := padicLocalIntegralBasis(p,disc,redDisc,prime)
-      [ib.basis,ib.basisDen,ib.basisInv]
-
-    listSquaredFactors: R -> List R
-    listSquaredFactors px ==
-      -- returns a list of the factors of px which occur with
-      -- exponent > 1
-      ans : List R := empty()
-      factored := factor(px)$DistinctDegreeFactorize(K,R)
-      for f in factors(factored) repeat
-        if f.exponent > 1 then ans := concat(f.factor,ans)
-      ans
-
-    integralBasis() ==
-      p := definingPolynomial()$F; disc := discriminant p; n := rank()$F
-      --traceMat := traceMatrix()$F; n := rank()$F
-      --disc := determinant traceMat        -- discriminant of current order
-      singList := listSquaredFactors disc -- singularities of relative Spec
-      redDisc := reducedDiscriminant p
-      runningRb := runningRbinv := scalarMatrix(n,1)$Mat
-      -- runningRb    = basis matrix of current order
-      -- runningRbinv = inverse basis matrix of current order
-      -- these are wrt the original basis for F
-      runningRbden : R := 1
-      -- runningRbden = denominator for current basis matrix
-      empty? singList => [runningRb, runningRbden, runningRbinv]
-      for prime in singList repeat
-        lb := padicLocalIntegralBasis(p,disc,redDisc,prime)
-        rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
-        disc := lb.discr
-        mat := vertConcat(rbden * runningRb,runningRbden * rb)
-        runningRbden := runningRbden * rbden
-        runningRb := squareTop rowEchelon(mat,runningRbden)
-        --runningRb := squareTop rowEch mat
-        runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
-      [runningRb, runningRbden, runningRbinv]
-
-@
-\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 IBPTOOLS IntegralBasisPolynomialTools>>
-<<package IBACHIN ChineseRemainderToolsForIntegralBases>>
-<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/paramete.spad.pamphlet b/src/algebra/paramete.spad.pamphlet
deleted file mode 100644
index cc85e58..0000000
--- a/src/algebra/paramete.spad.pamphlet
+++ /dev/null
@@ -1,92 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra paramete.spad}
-\author{Clifton J. Williamson}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PARPC2 ParametricPlaneCurveFunctions2}
-<<package PARPC2 ParametricPlaneCurveFunctions2>>=
-)abbrev package PARPC2 ParametricPlaneCurveFunctions2
-++ Description:
-++ This package \undocumented
-ParametricPlaneCurveFunctions2(CF1: Type, CF2:Type): with
-  map: (CF1 -> CF2, ParametricPlaneCurve(CF1)) -> ParametricPlaneCurve(CF2)
-	++ map(f,x) \undocumented
- == add
-  map(f, c) == curve(f coordinate(c,1), f coordinate(c, 2))
-
-@
-\section{package PARSC2 ParametricSpaceCurveFunctions2}
-<<package PARSC2 ParametricSpaceCurveFunctions2>>=
-)abbrev package PARSC2 ParametricSpaceCurveFunctions2
-++ Description:
-++ This package \undocumented
-ParametricSpaceCurveFunctions2(CF1: Type, CF2:Type): with
-  map: (CF1 -> CF2, ParametricSpaceCurve(CF1)) -> ParametricSpaceCurve(CF2)
-	++ map(f,x) \undocumented
- == add
-  map(f, c) == curve(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
-
-@
-\section{package PARSU2 ParametricSurfaceFunctions2}
-<<package PARSU2 ParametricSurfaceFunctions2>>=
-)abbrev package PARSU2 ParametricSurfaceFunctions2
-++ Description:
-++ This package \undocumented
-ParametricSurfaceFunctions2(CF1: Type, CF2:Type): with
-  map: (CF1 -> CF2, ParametricSurface(CF1)) -> ParametricSurface(CF2)
-	++ map(f,x) \undocumented
- == add
-  map(f, c) == surface(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
-
-@
-\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 PARPC2 ParametricPlaneCurveFunctions2>>
-<<package PARSC2 ParametricSpaceCurveFunctions2>>
-<<package PARSU2 ParametricSurfaceFunctions2>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/partperm.spad.pamphlet b/src/algebra/partperm.spad.pamphlet
deleted file mode 100644
index cbe6809..0000000
--- a/src/algebra/partperm.spad.pamphlet
+++ /dev/null
@@ -1,168 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra partperm.spad}
-\author{William Burge}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PARTPERM PartitionsAndPermutations}
-<<package PARTPERM PartitionsAndPermutations>>=
-)abbrev package PARTPERM PartitionsAndPermutations
-++ Author: William H. Burge
-++ Date Created: 29 October 1987
-++ Date Last Updated: 3 April 1991
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: partition, permutation
-++ References:
-++ Description: PartitionsAndPermutations contains
-++ functions for generating streams of integer partitions,
-++ and streams of sequences of integers
-++ composed from a multi-set.
-PartitionsAndPermutations: Exports == Implementation where
-  I   ==> Integer
-  L   ==> List
-  ST  ==> Stream
-  ST1 ==> StreamFunctions1
-  ST2 ==> StreamFunctions2
-  ST3 ==> StreamFunctions3
- 
-  Exports ==> with
- 
-    partitions: (I,I,I) -> ST L I
-      ++\spad{partitions(p,l,n)} is the stream of partitions
-      ++ of n whose number of parts is no greater than p
-      ++ and whose largest part is no greater than l.
-    partitions: I -> ST L I
-      ++\spad{partitions(n)} is the stream of all partitions of n.
-    partitions: (I,I) -> ST L I
-      ++\spad{partitions(p,l)} is the stream of all
-      ++ partitions whose number of
-      ++ parts and largest part are no greater than p and l.
-    conjugate: L I -> L I
-      ++\spad{conjugate(pt)} is the conjugate of the partition pt.
-    conjugates: ST L I -> ST L I
-      ++\spad{conjugates(lp)} is the stream of conjugates of a stream
-      ++ of partitions lp.
-    shuffle: (L I,L I) -> ST L I
-      ++\spad{shuffle(l1,l2)} forms the stream of all shuffles of l1
-      ++ and l2, i.e. all sequences that can be formed from
-      ++ merging l1 and l2.
-    shufflein: (L I,ST L I) -> ST L I
-      ++\spad{shufflein(l,st)} maps shuffle(l,u) on to all
-      ++ members u of st, concatenating the results.
-    sequences: (L I,L I) -> ST L I
-      ++\spad{sequences(l1,l2)} is the stream of all sequences that
-      ++ can be composed from the multiset defined from
-      ++ two lists of integers l1 and l2.
-      ++ For example,the pair \spad{([1,2,4],[2,3,5])} represents
-      ++ multi-set with 1 \spad{2}, 2 \spad{3}'s, and 4 \spad{5}'s.
-    sequences: L I -> ST L I
-      ++ \spad{sequences([l0,l1,l2,..,ln])} is the set of
-      ++  all sequences formed from
-      ++ \spad{l0} 0's,\spad{l1} 1's,\spad{l2} 2's,...,\spad{ln} n's.
-    permutations: I -> ST L I
-      ++\spad{permutations(n)} is the stream of permutations
-      ++ formed from \spad{1,2,3,...,n}.
- 
-  Implementation ==> add
- 
-    partitions(M,N,n) ==
-      zero? n => concat(empty()$L(I),empty()$(ST L I))
-      zero? M or zero? N or n < 0 => empty()
-      c := map(concat(N,#1),partitions(M - 1,N,n - N))
-      concat(c,partitions(M,N - 1,n))
- 
-    partitions n == partitions(n,n,n)
- 
-    partitions(M,N)==
-      aaa : L ST L I := [partitions(M,N,i) for i in 0..M*N]
-      concat(aaa :: ST ST L I)$ST1(L I)
- 
-    -- nogreq(n,l) is the number of elements of l that are greater or
-    -- equal to n
-    nogreq: (I,L I) -> I
-    nogreq(n,x) == +/[1 for i in x | i >= n]
- 
-    conjugate x ==
-      empty? x => empty()
-      [nogreq(i,x) for i in 1..first x]
- 
-    conjugates z == map(conjugate,z)
- 
-    shuffle(x,y)==
-      empty? x => concat(y,empty())$(ST L I)
-      empty? y => concat(x,empty())$(ST L I)
-      concat(map(concat(first x,#1),shuffle(rest x,y)),_
-             map(concat(first y,#1),shuffle(x,rest y)))
- 
-    shufflein(x,yy) ==
-      concat(map(shuffle(x,#1),yy)$ST2(L I,ST L I))$ST1(L I)
- 
-    -- rpt(n,m) is the list of n m's
-    rpt: (I,I) -> L I
-    rpt(n,m) == [m for i in 1..n]
- 
-    -- zrpt(x,y) where x is [x0,x1,x2...] and y is [y0,y1,y2...]
-    -- is the stream [rpt(x0,y0),rpt(x1,y1),...]
-    zrpt: (L I,L I) -> ST L I
-    zrpt(x,y) == map(rpt,x :: ST I,y :: ST I)$ST3(I,I,L I)
- 
-    sequences(x,y) ==
-      reduce(concat(empty()$L(I),empty()$(ST L I)),_
-                    shufflein,zrpt(x,y))$ST2(L I,ST L I)
- 
-    sequences x == sequences(x,[i for i in 0..#x-1])
- 
-    permutations n == sequences(rpt(n,1),[i for i in 1..n])
-
-@
-\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 PARTPERM PartitionsAndPermutations>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/patmatch1.spad.pamphlet b/src/algebra/patmatch1.spad.pamphlet
deleted file mode 100644
index 3cc20b6..0000000
--- a/src/algebra/patmatch1.spad.pamphlet
+++ /dev/null
@@ -1,546 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra patmatch1.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PATRES2 PatternMatchResultFunctions2}
-<<dot>>=
-"PATRES2" -> "PACKAGE"
-"PatternMatchResultFunctions2(a:SetCategory,b:SetCategory,c:SetCategory)" -> 
-    "Package"
-@
-<<package PATRES2 PatternMatchResultFunctions2>>=
-)abbrev package PATRES2 PatternMatchResultFunctions2
-++ Lifts maps to pattern matching results
-++ Author: Manuel Bronstein
-++ Date Created: 1 Dec 1989
-++ Date Last Updated: 14 Dec 1989
-++ Description: Lifts maps to pattern matching results.
-++ Keywords: pattern, matching.
-PatternMatchResultFunctions2(R, A, B): Exports == Implementation where
-  R: SetCategory
-  A: SetCategory
-  B: SetCategory
-
-  Exports ==> with
-    map: (A -> B, PatternMatchResult(R, A)) -> PatternMatchResult(R, B)
-      ++ map(f, [(v1,a1),...,(vn,an)]) returns the matching result
-      ++ [(v1,f(a1)),...,(vn,f(an))].
-
-  Implementation ==> add
-    map(f, r) ==
-      failed? r => failed()
-      construct [[rec.key, f(rec.entry)] for rec in destruct r]
-
-@
-\section{package PMSYM PatternMatchSymbol}
-<<dot>>=
-"PMSYM" -> "PACKAGE"
-"PatternMatchSymbol(a:SetCategory)" -> "Package"
-@
-<<package PMSYM PatternMatchSymbol>>=
-)abbrev package PMSYM PatternMatchSymbol
-++ Pattern matching on symbols
-++ Author: Manuel Bronstein
-++ Date Created: 9 Jan 1990
-++ Date Last Updated: 20 June 1991
-++ Description:
-++   This package provides pattern matching functions on symbols.
-++ Keywords: pattern, matching, symbol.
-PatternMatchSymbol(S:SetCategory): with
-  patternMatch: (Symbol, Pattern S, PatternMatchResult(S, Symbol)) ->
-                                           PatternMatchResult(S, Symbol)
-    ++ patternMatch(expr, pat, res) matches the pattern pat to the
-    ++ expression expr; res contains the variables of pat which
-    ++ are already matched and their matches (necessary for recursion).
- == add
-  import TopLevelPatternMatchControl
-
-  patternMatch(s, p, l) ==
-    generic? p  => addMatch(p, s, l)
-    constant? p =>
-      ((u := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
-        and (u::Symbol) = s => l
-      failed()
-    failed()
-
-@
-\section{package PMKERNEL PatternMatchKernel}
-<<dot>>=
-"PMKERNEL" -> "PACKAGE"
-"PatternMatchKernel(a:SetCategory, b:Join(...))" -> "Package"
-@
-<<package PMKERNEL PatternMatchKernel>>=
-)abbrev package PMKERNEL PatternMatchKernel
-++ Pattern matching on kernels
-++ Author: Manuel Bronstein
-++ Date Created: 12 Jan 1990
-++ Date Last Updated: 4 May 1992
-++ Description:
-++   This package provides pattern matching functions on kernels.
-++ Keywords: pattern, matching, kernel.
-PatternMatchKernel(S, E): Exports == Implementation where
-  S: SetCategory
-  E: Join(OrderedSet, RetractableTo Kernel %,
-          ConvertibleTo Pattern S, PatternMatchable S)
-
-  PAT ==> Pattern S
-  PRS ==> PatternMatchResult(S, E)
-  POWER ==> "%power"::Symbol
-  NTHRT ==> "nthRoot"::Symbol
-
-  Exports ==> with
-    patternMatch: (Kernel E, PAT, PRS) -> PRS
-      ++ patternMatch(f(e1,...,en), pat, res) matches the pattern pat
-      ++ to \spad{f(e1,...,en)}; res contains the variables of pat which
-      ++ are already matched and their matches.
-
-  Implementation ==> add
-    patternMatchArg  : (List E, List PAT, PRS) -> PRS
-    patternMatchInner: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
-
-    -- matches the ordered lists ls and lp.
-    patternMatchArg(ls, lp, l) ==
-      #ls ^= #lp => failed()
-      for p in lp for s in ls repeat
-        generic? p and failed?(l := addMatch(p,s,l)) => return failed()
-      for p in lp for s in ls repeat
-        not(generic? p) and failed?(l := patternMatch(s, p, l)) =>
-                                                         return failed()
-      l
-
-    patternMatchInner(s, p, l) ==
-      generic? p => addMatch(p, s::E, l)
-      (u := isOp p) case Record(op:BasicOperator, arg: List PAT) =>
-        ur := u::Record(op:BasicOperator, arg: List PAT)
-        ur.op = operator s => patternMatchArg(argument s, ur.arg, l)
-        failed()
-      constant? p =>
-        ((v := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
-          and ((w := symbolIfCan s) case Symbol) and
-            (v::Symbol = w::Symbol) => l
-        failed()
-      "failed"
-
-    if E has Monoid then
-      patternMatchMonoid: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
-      patternMatchOpt   : (E, List PAT, PRS, E) -> PRS
-
-      patternMatchOpt(x, lp, l, id) ==
-        (u := optpair lp) case List(PAT) =>
-          failed?(l := addMatch(first(u::List(PAT)), id, l)) => failed()
-          patternMatch(x, second(u::List(PAT)), l)
-        failed()
-
-      patternMatchMonoid(s, p, l) ==
-        (u := patternMatchInner(s, p, l)) case PRS => u::PRS
-        (v := isPower p) case Record(val:PAT, exponent:PAT) =>
-          vr := v::Record(val:PAT, exponent: PAT)
-          is?(op := operator s, POWER) =>
-            patternMatchArg(argument s, [vr.val, vr.exponent], l)
-          is?(op,NTHRT) and ((r := recip(second(arg := argument s))) case E) =>
-            patternMatchArg([first arg, r::E], [vr.val, vr.exponent], l)
-          optional?(vr.exponent) =>
-            failed?(l := addMatch(vr.exponent, 1, l)) => failed()
-            patternMatch(s::E, vr.val, l)
-          failed()
-        (w := isTimes p) case List(PAT) =>
-          patternMatchOpt(s::E, w::List(PAT), l, 1)
-        "failed"
-
-      if E has AbelianMonoid then
-        patternMatch(s, p, l) ==
-          (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
-          (w := isPlus p) case List(PAT) =>
-            patternMatchOpt(s::E, w::List(PAT), l, 0)
-          failed()
-
-      else
-        patternMatch(s, p, l) ==
-          (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
-          failed()
-
-    else
-      patternMatch(s, p, l) ==
-        (u := patternMatchInner(s, p, l)) case PRS => u::PRS
-        failed()
-
-@
-\section{package PMDOWN PatternMatchPushDown}
-<<dot>>=
-"PMDOWN" -> "PACKAGE"
-"PatternMatchPushDown(a:SETCAT, b:PATMAB(SETCAT), c:Join(...))"
-    -> "Package"
-@
-<<package PMDOWN PatternMatchPushDown>>=
-)abbrev package PMDOWN PatternMatchPushDown
-++ Pattern matching in towers
-++ Author: Manuel Bronstein
-++ Date Created: 1 Dec 1989
-++ Date Last Updated: 16 August 1995
-++ Description:
-++   This packages provides tools for matching recursively
-++   in type towers.
-++ Keywords: pattern, matching, quotient, field.
-PatternMatchPushDown(S, A, B): Exports == Implementation where
-  S: SetCategory
-  A: PatternMatchable S
-  B: Join(SetCategory, RetractableTo A)
-
-  PAT ==> Pattern S
-  PRA ==> PatternMatchResult(S, A)
-  PRB ==> PatternMatchResult(S, B)
-  REC ==> Record(pat:PAT, res:PRA)
-
-  Exports ==> with
-    fixPredicate: (B -> Boolean) -> (A -> Boolean)
-      ++ fixPredicate(f) returns g defined by g(a) = f(a::B);
-    patternMatch: (A, PAT, PRB)  -> PRB
-      ++ patternMatch(expr, pat, res) matches the pattern pat to the
-      ++ expression expr; res contains the variables of pat which
-      ++ are already matched and their matches.
-      ++ Note: this function handles type towers by changing the predicates
-      ++ and calling the matching function provided by \spad{A}.
-
-  Implementation ==> add
-    import PatternMatchResultFunctions2(S, A, B)
-
-    fixPred      : Any -> Union(Any, "failed")
-    inA          : (PAT, PRB) -> Union(List A, "failed")
-    fixPredicates: (PAT, PRB, PRA) -> Union(REC, "failed")
-    fixList:(List PAT -> PAT, List PAT, PRB, PRA) -> Union(REC,"failed")
-
-    fixPredicate f == f(#1::B)
-
-    patternMatch(a, p, l) ==
-      (u := fixPredicates(p, l, new())) case "failed" => failed()
-      union(l, map(#1::B, patternMatch(a, (u::REC).pat, (u::REC).res)))
-
-    inA(p, l) ==
-      (u := getMatch(p, l)) case "failed" => empty()
-      (r := retractIfCan(u::B)@Union(A, "failed")) case A => [r::A]
-      "failed"
-
-    fixList(fn, l, lb, la) ==
-      ll:List(PAT) := empty()
-      for x in l repeat
-        (f := fixPredicates(x, lb, la)) case "failed" => return "failed"
-        ll := concat((f::REC).pat, ll)
-        la := (f::REC).res
-      [fn ll, la]
-
-    fixPred f ==
-      (u:= retractIfCan(f)$AnyFunctions1(B -> Boolean)) case "failed" =>
-                                                                "failed"
-      g := fixPredicate(u::(B -> Boolean))
-      coerce(g)$AnyFunctions1(A -> Boolean)
-
-    fixPredicates(p, lb, la) ==
-      (r:=retractIfCan(p)@Union(S,"failed")) case S or quoted? p =>[p,la]
-      (u := isOp p) case Record(op:BasicOperator, arg:List PAT) =>
-        ur := u::Record(op:BasicOperator, arg:List PAT)
-        fixList((ur.op) #1, ur.arg, lb, la)
-      (us := isPlus p) case List(PAT) =>
-        fixList(reduce("+", #1), us::List(PAT), lb, la)
-      (us := isTimes p) case List(PAT) =>
-        fixList(reduce("*", #1), us::List(PAT), lb, la)
-      (v := isQuotient p) case Record(num:PAT, den:PAT) =>
-        vr := v::Record(num:PAT, den:PAT)
-        (fn := fixPredicates(vr.num, lb, la)) case "failed" => "failed"
-        la  := (fn::REC).res
-        (fd := fixPredicates(vr.den, lb, la)) case "failed" => "failed"
-        [(fn::REC).pat / (fd::REC).pat, (fd::REC).res]
-      (w:= isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
-        wr := w::Record(val:PAT, exponent: NonNegativeInteger)
-        (f := fixPredicates(wr.val, lb, la)) case "failed" => "failed"
-        [(f::REC).pat ** wr.exponent, (f::REC).res]
-      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
-        uur := uu::Record(val:PAT, exponent: PAT)
-        (fv := fixPredicates(uur.val, lb, la)) case "failed" => "failed"
-        la  := (fv::REC).res
-        (fe := fixPredicates(uur.exponent, lb, la)) case "failed" =>
-          "failed"
-        [(fv::REC).pat ** (fe::REC).pat, (fe::REC).res]
-      generic? p =>
-        (ua := inA(p, lb)) case "failed" => "failed"
-        lp := [if (h := fixPred g) case Any then h::Any else
-                        return "failed" for g in predicates p]$List(Any)
-        q := setPredicates(patternVariable(retract p, constant? p,
-                                           optional? p, multiple? p), lp)
-        [q, (empty?(ua::List A) => la; insertMatch(q,first(ua::List A), la))]
-      error "Should not happen"
-
-@
-\section{package PMTOOLS PatternMatchTools}
-<<dot>>=
-"PMTOOLS" -> "PACKAGE"
-"PatternMatchTools(a:SetCategory,b:Join(...),c:Join(...))" -> "Package"
-@
-<<package PMTOOLS PatternMatchTools>>=
-)abbrev package PMTOOLS PatternMatchTools
-++ Tools for the pattern matcher
-++ Author: Manuel Bronstein
-++ Date Created: 13 Mar 1990
-++ Date Last Updated: 4 February 1992
-++ Description:
-++   This package provides tools for the pattern matcher.
-++ Keywords: pattern, matching, tools.
-PatternMatchTools(S, R, P): Exports == Implementation where
-  S: SetCategory
-  R: Join(Ring, OrderedSet)
-  P: Join(Ring, ConvertibleTo Pattern S, RetractableTo R)
-
-  PAT ==> Pattern S
-  PRS ==> PatternMatchResult(S, P)
-  REC ==> Record(res:PRS, s:List P)
-  RC  ==> Record(pat:List PAT, s:List P)
-
-  Exports ==> with
-    patternMatch: (List P, List PAT, List P -> P, PRS,
-                                            (P, PAT, PRS) -> PRS) -> PRS
-      ++ patternMatch(lsubj, lpat, op, res, match) matches the list
-      ++ of patterns lpat to the list of subjects lsubj, allowing for
-      ++ commutativity; op is the operator such that op(lpat) should
-      ++ match op(lsubj) at the end, r contains the previous matches,
-      ++ and match is a pattern-matching function on P.
-    patternMatchTimes: (List P, List PAT, PRS,
-                                            (P, PAT, PRS) -> PRS) -> PRS
-      ++ patternMatchTimes(lsubj, lpat, res, match) matches the
-      ++ product of patterns \spad{reduce(*,lpat)}
-      ++ to the product of subjects \spad{reduce(*,lsubj)};
-      ++ r contains the previous matches
-      ++ and match is a pattern-matching function on P.
-
-  Implementation ==> add
-    import PatternFunctions1(S, P)
-
-    preprocessList: (PAT, List P, PRS) -> Union(List P, "failed")
-    selBestGen    : List PAT -> List PAT
-    negConstant   : List P -> Union(P, "failed")
-    findMatch     : (PAT, List P, PRS, P, (P, PAT, PRS) -> PRS) -> REC
-    tryToMatch    : (List PAT, REC, P, (P, PAT, PRS) -> PRS) ->
-                                                  Union(REC, "failed")
-    filterMatchedPatterns: (List PAT, List P, PRS) -> Union(RC, "failed")
-
-    mn1 := convert(-1::P)@Pattern(S)
-
-    negConstant l ==
-      for x in l repeat
-        ((r := retractIfCan(x)@Union(R, "failed")) case R) and
-          (r::R < 0) => return x
-      "failed"
-
--- tries to match the list of patterns lp to the list of subjects rc.s
--- with rc.res being the list of existing matches.
--- updates rc with the new result and subjects still to match
-    tryToMatch(lp, rc, ident, pmatch) ==
-      rec:REC := [l := rc.res, ls := rc.s]
-      for p in lp repeat
-        rec := findMatch(p, ls, l, ident, pmatch)
-        failed?(l := rec.res) => return "failed"
-        ls := rec.s
-      rec
-
--- handles -1 in the pattern list.
-    patternMatchTimes(ls, lp, l, pmatch) ==
-      member?(mn1, lp) =>
-        (u := negConstant ls) case "failed" => failed()
-        if (u::P ^= -1::P) then ls := concat(-u::P, ls)
-        patternMatch(remove(u::P,ls), remove(mn1,lp), */#1, l, pmatch)
-      patternMatch(ls, lp, */#1, l, pmatch)
-
--- finds a match for p in ls, try not to match to a "bad" value
-    findMatch(p, ls, l, ident, pmatch) ==
-      bad:List(P) :=
-        generic? p => setIntersection(badValues p, ls)
-        empty()
-      l1:PRS := failed()
-      for x in setDifference(ls, bad)
-        while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
-      failed? l1 =>
-        for x in bad
-          while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
-        failed? l1 => [addMatchRestricted(p, ident, l, ident), ls]
-        [l1, remove(t, ls)]
-      [l1, remove(t, ls)]
-
--- filters out pattern if it's generic and already matched.
-    preprocessList(pattern, ls, l) ==
-      generic? pattern =>
-        (u := getMatch(pattern, l)) case P =>
-          member?(u::P, ls) => [u::P]
-          "failed"
-        empty()
-      empty()
-
--- take out already matched generic patterns
-    filterMatchedPatterns(lp, ls, l) ==
-      for p in lp repeat
-        (rc := preprocessList(p, ls, l)) case "failed" => return "failed"
-        if not empty?(rc::List(P)) then
-          lp := remove(p,  lp)
-          ls := remove(first(rc::List(P)), ls)
-      [lp, ls]
-
--- select a generic pattern with no predicate if possible
-    selBestGen l ==
-      ans := empty()$List(PAT)
-      for p in l | generic? p repeat
-        ans := [p]
-        not hasPredicate? p => return ans
-      ans
-
--- matches unordered lists ls and lp
-    patternMatch(ls, lp, op, l, pmatch) ==
-      ident := op empty()
-      (rc := filterMatchedPatterns(lp, ls, l)) case "failed" => return failed()
-      lp := (rc::RC).pat
-      ls := (rc::RC).s
-      empty? lp => l
-      #(lpm := select(optional?, lp)) > 1 =>
-        error "More than one optional pattern in sum/product"
-      (#ls + #lpm) < #lp => failed()
-      if (not empty? lpm) and (#ls + 1 = #lp) then
-        lp := remove(first lpm, lp)
-        failed?(l := addMatch(first lpm, ident, l)) => return l
-      #(lpm := select(multiple?, lp)) > 1 =>
-        error "More than one expandable pattern in sum/product"
-      #ls > #lp and empty? lpm and empty?(lpm := selBestGen lp) =>
-        failed()
-      if not empty? lpm then lp := remove(first lpm, lp)
-      -- this is the order in which we try to match predicates
-      -- l1 = constant patterns (i.e. 'x, or sin('x))
-      l1 := select(constant?, lp)
-      -- l2 = patterns with a predicate attached to them
-      l2 := select(hasPredicate? #1 and not constant? #1, lp)
-      -- l3 = non-generic patterns without predicates
-      l3 := sort_!(depth(#1) > depth(#2),
-        select(not(hasPredicate? #1 or generic? #1 or constant? #1),lp))
-      -- l4 = generic patterns with predicates
-      l4 := select(generic? #1 and
-                              not(hasPredicate? #1 or constant? #1), lp)
-      rec:REC := [l, ls]
-      (u := tryToMatch(l1, rec, ident, pmatch)) case "failed" =>
-        failed()
-      (u := tryToMatch(l2, u::REC, ident, pmatch)) case "failed" =>
-        failed()
-      (u := tryToMatch(l3, u::REC, ident, pmatch)) case "failed" =>
-        failed()
-      rec := u::REC
-      (rc := filterMatchedPatterns(l4,rec.s,rec.res)) case "failed" => failed()
-      rec := [rec.res, (rc::RC).s]
-      (u := tryToMatch((rc::RC).pat,rec,ident,pmatch)) case "failed" => failed()
-      rec := u::REC
-      l := rec.res
-      ls := rec.s
-      empty? lpm =>
-        empty? ls => l
-        failed()
-      addMatch(first lpm, op ls, l)
-
-@
-\section{package PMLSAGG PatternMatchListAggregate}
-<<dot>>=
-"PMLSAGG" -> "PACKAGE"
-"PatternMatchListAggregate(a:SETCAT,b:PATMAB(SETCAT),c:LSAGG(PATMAB(SETCAT)))"
-    -> "Package"
-@
-<<package PMLSAGG PatternMatchListAggregate>>=
-)abbrev package PMLSAGG PatternMatchListAggregate
-++ Pattern matching for list aggregates
-++ Author: Manuel Bronstein
-++ Date Created: 4 Dec 1989
-++ Date Last Updated: 29 Jun 1990
-++ Description:
-++   This package provides pattern matching functions on lists.
-++ Keywords: pattern, matching, list.
-PatternMatchListAggregate(S, R, L): Exports == Implementation where
-  S: SetCategory
-  R: PatternMatchable S
-  L: ListAggregate R
-
-  PLR ==> PatternMatchListResult(S, R, L)
-
-  Exports ==> with
-    patternMatch: (L, Pattern S, PLR) -> PLR
-      ++ patternMatch(l, pat, res) matches the pattern pat to the
-      ++ list l; res contains the variables of pat which
-      ++ are already matched and their matches.
-
-  Implementation ==> add
-    match: (L, List Pattern S, PLR, Boolean) -> PLR
-
-    patternMatch(l, p, r) ==
-      (u := isList p) case "failed" => failed()
-      match(l, u::List Pattern S, r, true)
-
-    match(l, lp, r, new?) ==
-      empty? lp =>
-        empty? l => r
-        failed()
-      multiple?(p0 := first lp) =>
-        empty? rest lp =>
-          if not new? then l := reverse_! l
-          makeResult(atoms r, addMatchRestricted(p0,l,lists r,empty()))
-        new? => match(reverse l, reverse lp, r, false)
-        error "Only one multiple pattern allowed in list"
-      empty? l => failed()
-      failed?(r := makeResult(patternMatch(first l,p0,atoms r),lists r))
-                                                             => failed()
-      match(rest l, rest lp, r, new?)
-
-@
-\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 PATRES2 PatternMatchResultFunctions2>>
-<<package PMSYM PatternMatchSymbol>>
-<<package PMKERNEL PatternMatchKernel>>
-<<package PMDOWN PatternMatchPushDown>>
-<<package PMTOOLS PatternMatchTools>>
-<<package PMLSAGG PatternMatchListAggregate>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/patmatch2.spad.pamphlet b/src/algebra/patmatch2.spad.pamphlet
deleted file mode 100644
index 0c86c74..0000000
--- a/src/algebra/patmatch2.spad.pamphlet
+++ /dev/null
@@ -1,404 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra patmatch2.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PMINS PatternMatchIntegerNumberSystem}
-<<package PMINS PatternMatchIntegerNumberSystem>>=
-)abbrev package PMINS PatternMatchIntegerNumberSystem
-++ Pattern matching on integer number systems
-++ Author: Manuel Bronstein
-++ Date Created: 29 Nov 1989
-++ Date Last Updated: 22 Mar 1990
-++ Description:
-++   This package provides pattern matching functions on integers.
-++ Keywords: pattern, matching, integer.
-PatternMatchIntegerNumberSystem(I:IntegerNumberSystem): with
-  patternMatch: (I, Pattern Integer, PatternMatchResult(Integer, I)) ->
-                                          PatternMatchResult(Integer, I)
-    ++ patternMatch(n, pat, res) matches the pattern pat to the
-    ++ integer n; res contains the variables of pat which
-    ++ are already matched and their matches.
- == add
-   import IntegerRoots(I)
-
-   PAT ==> Pattern Integer
-   PMR ==> PatternMatchResult(Integer, I)
-
-   patternMatchInner     : (I, PAT, PMR) -> PMR
-   patternMatchRestricted: (I, PAT, PMR, I) -> PMR
-   patternMatchSumProd   :
-     (I, List PAT, PMR, (I, I) -> Union(I, "failed"), I) -> PMR
-
-   patternMatch(x, p, l) ==
-     generic? p => addMatch(p, x, l)
-     patternMatchInner(x, p, l)
-
-   patternMatchRestricted(x, p, l, y) ==
-     generic? p => addMatchRestricted(p, x, l, y)
-     patternMatchInner(x, p, l)
-
-   patternMatchSumProd(x, lp, l, invOp, ident) ==
-     #lp = 2 =>
-       p2 := last lp
-       if ((r:= retractIfCan(p1 := first lp)@Union(Integer,"failed"))
-                          case "failed") then (p1 := p2; p2 := first lp)
-       (r := retractIfCan(p1)@Union(Integer, "failed")) case "failed" =>
-                                                                failed()
-       (y := invOp(x, r::Integer::I)) case "failed" => failed()
-       patternMatchRestricted(y::I, p2, l, ident)
-     failed()
-
-   patternMatchInner(x, p, l) ==
-     constant? p =>
-       (r := retractIfCan(p)@Union(Integer, "failed")) case Integer =>
-         convert(x)@Integer = r::Integer => l
-         failed()
-       failed()
-     (u := isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
-       ur := u::Record(val:PAT, exponent:NonNegativeInteger)
-       (v := perfectNthRoot(x, ur.exponent)) case "failed" => failed()
-       patternMatchRestricted(v::I, ur.val, l, 1)
-     (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
-       uur := uu::Record(val:PAT, exponent: PAT)
-       pr := perfectNthRoot x
-       failed?(l := patternMatchRestricted(pr.exponent::Integer::I,
-                                         uur.exponent, l,1)) => failed()
-       patternMatchRestricted(pr.base, uur.val, l, 1)
-     (w := isTimes p) case List(PAT) =>
-       patternMatchSumProd(x, w::List(PAT), l, #1 exquo #2, 1)
-     (w := isPlus p) case List(PAT) =>
-      patternMatchSumProd(x,w::List(PAT),l,(#1-#2)::Union(I,"failed"),0)
-     (uv := isQuotient p) case Record(num:PAT, den:PAT) =>
-       uvr := uv::Record(num:PAT, den:PAT)
-       (r := retractIfCan(uvr.num)@Union(Integer,"failed")) case Integer
-         and (v := r::Integer::I exquo x) case I =>
-           patternMatchRestricted(v::I, uvr.den, l, 1)
-       (r := retractIfCan(uvr.den)@Union(Integer,"failed")) case Integer
-         => patternMatch(r::Integer * x, uvr.num, l)
-       failed()
-     failed()
-
-@
-\section{package PMQFCAT PatternMatchQuotientFieldCategory}
-<<package PMQFCAT PatternMatchQuotientFieldCategory>>=
-)abbrev package PMQFCAT PatternMatchQuotientFieldCategory
-++ Pattern matching on quotient objects
-++ Author: Manuel Bronstein
-++ Date Created: 1 Dec 1989
-++ Date Last Updated: 20 June 1991
-++ Description:
-++   This package provides pattern matching functions on quotients.
-++ Keywords: pattern, matching, quotient, field.
-PatternMatchQuotientFieldCategory(S,R,Q):Exports == Implementation where
-  S: SetCategory
-  R: Join(IntegralDomain, PatternMatchable S, ConvertibleTo Pattern S)
-  Q: QuotientFieldCategory R
-
-  PAT ==> Pattern S
-  PRQ ==> PatternMatchResult(S, Q)
-
-  Exports ==> with
-    patternMatch: (Q, PAT, PRQ) -> PRQ
-      ++ patternMatch(a/b, pat, res) matches the pattern pat to the
-      ++ quotient a/b; res contains the variables of pat which
-      ++ are already matched and their matches.
-
-  Implementation ==> add
-    import PatternMatchPushDown(S, R, Q)
-
-    patternMatch(x, p, l) ==
-      generic? p => addMatch(p, x, l)
-      (r := retractIfCan x)@Union(R, "failed") case R =>
-        patternMatch(r::R, p, l)
-      (u := isQuotient p) case Record(num:PAT, den:PAT) =>
-        ur := u::Record(num:PAT, den:PAT)
-        failed?(l := patternMatch(numer x, ur.num, l)) => l
-        patternMatch(denom x, ur.den, l)
-      failed()
-
-@
-\section{package PMPLCAT PatternMatchPolynomialCategory}
-<<package PMPLCAT PatternMatchPolynomialCategory>>=
-)abbrev package PMPLCAT PatternMatchPolynomialCategory
-++ Pattern matching on polynomial objects
-++ Author: Manuel Bronstein
-++ Date Created: 9 Jan 1990
-++ Date Last Updated: 20 June 1991
-++ Description:
-++   This package provides pattern matching functions on polynomials.
-++ Keywords: pattern, matching, polynomial.
-PatternMatchPolynomialCategory(S,E,V,R,P):Exports== Implementation where
-  S: SetCategory
-  E: OrderedAbelianMonoidSup
-  V: OrderedSet
-  R: Join(Ring, OrderedSet, PatternMatchable S)
-  P: Join(PolynomialCategory(R, E, V), ConvertibleTo Pattern S)
-
-  N   ==> NonNegativeInteger
-  PAT ==> Pattern S
-  PRS ==> PatternMatchResult(S, P)
-  RCP ==> Record(val:PAT, exponent:N)
-  RCX ==> Record(var:V, exponent:N)
-
-  Exports ==> with
-    patternMatch: (P, PAT, PRS, (V, PAT, PRS) -> PRS) -> PRS
-      ++ patternMatch(p, pat, res, vmatch) matches the pattern pat to
-      ++ the polynomial p. res contains the variables of pat which
-      ++ are already matched and their matches; vmatch is the matching
-      ++ function to use on the variables.
-      -- This can be more efficient than pushing down when the variables
-      -- are recursive over P (e.g. kernels)
-    if V has PatternMatchable S then
-      patternMatch: (P, PAT, PRS) -> PRS
-        ++ patternMatch(p, pat, res) matches the pattern pat to
-        ++ the polynomial p; res contains the variables of pat which
-        ++ are already matched and their matches.
-
-  Implementation ==> add
-    import PatternMatchTools(S, R, P)
-    import PatternMatchPushDown(S, R, P)
-
-    if V has PatternMatchable S then
-      patternMatch(x, p, l) ==
-        patternMatch(x, p, l, patternMatch$PatternMatchPushDown(S,V,P))
-
-    patternMatch(x, p, l, vmatch) ==
-      generic? p => addMatch(p, x, l)
-      (r := retractIfCan(x)@Union(R, "failed")) case R =>
-        patternMatch(r::R, p, l)
-      (v := retractIfCan(x)@Union(V, "failed")) case V =>
-        vmatch(v::V, p, l)
-      (u := isPlus p) case List(PAT) =>
-        (lx := isPlus x) case List(P) =>
-          patternMatch(lx::List(P), u::List(PAT), +/#1, l,
-                                       patternMatch(#1, #2, #3, vmatch))
-        (u := optpair(u::List(PAT))) case List(PAT) =>
-          failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
-          patternMatch(x, second(u::List(PAT)), l, vmatch)
-        failed()
-      (u := isTimes p) case List(PAT) =>
-        (lx := isTimes x) case List(P) =>
-          patternMatchTimes(lx::List(P), u::List(PAT), l,
-                                       patternMatch(#1, #2, #3, vmatch))
-        (u := optpair(u::List(PAT))) case List(PAT) =>
-          failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
-          patternMatch(x, second(u::List(PAT)), l, vmatch)
-        failed()
-      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
-        uur := uu::Record(val:PAT, exponent: PAT)
-        (ex := isExpt x) case RCX =>
-          failed?(l := patternMatch((ex::RCX).exponent::Integer::P,
-                                   uur.exponent, l, vmatch)) => failed()
-          vmatch((ex::RCX).var, uur.val, l)
-        optional?(uur.exponent) =>
-          failed?(l := addMatch(uur.exponent, 1, l)) => failed()
-          patternMatch(x, uur.val, l, vmatch)
-        failed()
-      ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
-           (ex::RCX).exponent = (ep::RCP).exponent =>
-               vmatch((ex::RCX).var, (ep::RCP).val, l)
-      failed()
-
-@
-\section{package PMFS PatternMatchFunctionSpace}
-<<package PMFS PatternMatchFunctionSpace>>=
-)abbrev package PMFS PatternMatchFunctionSpace
-++ Pattern matching on function spaces
-++ Author: Manuel Bronstein
-++ Date Created: 15 Mar 1990
-++ Date Last Updated: 20 June 1991
-++ Description:
-++  This package provides pattern matching functions on function spaces.
-++ Keywords: pattern, matching, function, space.
-PatternMatchFunctionSpace(S, R, F): Exports== Implementation where
-  S: SetCategory
-  R: Join(IntegralDomain, OrderedSet, PatternMatchable S)
-  F: Join(FunctionSpace R, ConvertibleTo Pattern S, PatternMatchable S,
-          RetractableTo Kernel %)  -- that one is redundant but won't
-                                   -- compile without it
-
-  N   ==> NonNegativeInteger
-  K   ==> Kernel F
-  PAT ==> Pattern S
-  PRS ==> PatternMatchResult(S, F)
-  RCP ==> Record(val:PAT, exponent:N)
-  RCX ==> Record(var:K, exponent:Integer)
-
-  Exports ==> with
-    patternMatch: (F, PAT, PRS) -> PRS
-      ++ patternMatch(expr, pat, res) matches the pattern pat to the
-      ++ expression expr; res contains the variables of pat which
-      ++ are already matched and their matches.
-
-  Implementation ==> add
-    import PatternMatchKernel(S, F)
-    import PatternMatchTools(S, R, F)
-    import PatternMatchPushDown(S, R, F)
-
-    patternMatch(x, p, l) ==
-      generic? p => addMatch(p, x, l)
-      (r := retractIfCan(x)@Union(R, "failed")) case R =>
-        patternMatch(r::R, p, l)
-      (v := retractIfCan(x)@Union(K, "failed")) case K =>
-        patternMatch(v::K, p, l)
-      (q := isQuotient p) case Record(num:PAT, den:PAT) =>
-        uq := q::Record(num:PAT, den:PAT)
-        failed?(l := patternMatch(numer(x)::F, uq.num, l)) => l
-        patternMatch(denom(x)::F, uq.den, l)
-      (u := isPlus p) case List(PAT) =>
-        (lx := isPlus x) case List(F) =>
-          patternMatch(lx::List(F), u::List(PAT), +/#1, l, patternMatch)
-        (u := optpair(u::List(PAT))) case List(PAT) =>
-          failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
-          patternMatch(x, second(u::List(PAT)), l)
-        failed()
-      (u := isTimes p) case List(PAT) =>
-        (lx := isTimes x) case List(F) =>
-          patternMatchTimes(lx::List(F), u::List(PAT), l, patternMatch)
-        (u := optpair(u::List(PAT))) case List(PAT) =>
-          failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
-          patternMatch(x, second(u::List(PAT)), l)
-        failed()
-      (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
-        uur := uu::Record(val:PAT, exponent: PAT)
-        (ex := isExpt x) case RCX =>
-          failed?(l := patternMatch((ex::RCX).exponent::Integer::F,
-                                           uur.exponent, l)) => failed()
-          patternMatch((ex::RCX).var, uur.val, l)
-        optional?(uur.exponent) =>
-          failed?(l := addMatch(uur.exponent, 1, l)) => failed()
-          patternMatch(x, uur.val, l)
-        failed()
-      ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
-           (ex::RCX).exponent = ((ep::RCP).exponent)::Integer =>
-               patternMatch((ex::RCX).var, (ep::RCP).val, l)
-      failed()
-
-@
-\section{package PATMATCH PatternMatch}
-<<package PATMATCH PatternMatch>>=
-)abbrev package PATMATCH PatternMatch
-++ Top-level pattern matching functions
-++ Author: Manuel Bronstein
-++ Date Created: 3 Dec 1989
-++ Date Last Updated: 29 Jun 1990
-++ Description:
-++   This package provides the top-level pattern macthing functions.
-++ Keywords: pattern, matching.
-PatternMatch(Base, Subject, Pat): Exports == Implementation where
-  Base   : SetCategory
-  Subject: PatternMatchable Base
-  Pat    : ConvertibleTo Pattern Base
-
-  Exports ==> with
-    is?: (Subject, Pat)      -> Boolean
-      ++ is?(expr, pat) tests if the expression expr matches
-      ++ the pattern pat.
-    is?: (List Subject, Pat) -> Boolean
-      ++ is?([e1,...,en], pat) tests if the list of
-      ++ expressions \spad{[e1,...,en]} matches
-      ++ the pattern pat.
-    Is : (List Subject, Pat) ->
-                     PatternMatchListResult(Base, Subject, List Subject)
-      ++ Is([e1,...,en], pat) matches the pattern pat on the list of
-      ++ expressions \spad{[e1,...,en]} and returns the result.
-    if Subject has RetractableTo(Symbol) then
-      Is: (Subject, Pat) -> List Equation Subject
-        ++ Is(expr, pat) matches the pattern pat on the expression
-        ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
-        ++ returns an empty list if either expr is exactly equal to
-        ++ pat or if pat does not match expr.
-    else
-      if Subject has Ring then
-        Is: (Subject, Pat) -> List Equation Polynomial Subject
-          ++ Is(expr, pat) matches the pattern pat on the expression
-          ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
-          ++ returns an empty list if either expr is exactly equal to
-          ++ pat or if pat does not match expr.
-      else
-        Is: (Subject, Pat) -> PatternMatchResult(Base, Subject)
-          ++ Is(expr, pat) matches the pattern pat on the expression
-          ++ expr and returns a match of the form \spad{[v1 = e1,...,vn = en]};
-          ++ returns an empty match if expr is exactly equal to pat.
-          ++ returns a \spadfun{failed} match if pat does not match expr.
-
-  Implementation ==> add
-    import PatternMatchListAggregate(Base, Subject, List Subject)
-
-    ist: (Subject, Pat) -> PatternMatchResult(Base, Subject)
-
-    ist(s, p)                  == patternMatch(s, convert p, new())
-    is?(s:     Subject, p:Pat) == not failed? ist(s, p)
-    is?(s:List Subject, p:Pat) == not failed? Is(s, p)
-    Is(s:List Subject,  p:Pat) == patternMatch(s, convert p, new())
-
-    if Subject has RetractableTo(Symbol) then
-      Is(s:Subject, p:Pat):List(Equation Subject) ==
-        failed?(r := ist(s, p)) => empty()
-        [rec.key::Subject = rec.entry for rec in destruct r]
-
-    else
-      if Subject has Ring then
-        Is(s:Subject, p:Pat):List(Equation Polynomial Subject) ==
-          failed?(r := ist(s, p)) => empty()
-          [rec.key::Polynomial(Subject) =$Equation(Polynomial Subject)
-           rec.entry::Polynomial(Subject) for rec in destruct r]
-
-      else
-        Is(s:Subject,p:Pat):PatternMatchResult(Base,Subject) == ist(s,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 PMINS PatternMatchIntegerNumberSystem>>
-<<package PMQFCAT PatternMatchQuotientFieldCategory>>
-<<package PMPLCAT PatternMatchPolynomialCategory>>
-<<package PMFS PatternMatchFunctionSpace>>
-<<package PATMATCH PatternMatch>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pattern.spad.pamphlet b/src/algebra/pattern.spad.pamphlet
deleted file mode 100644
index d4e899f..0000000
--- a/src/algebra/pattern.spad.pamphlet
+++ /dev/null
@@ -1,166 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pattern.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PATTERN1 PatternFunctions1}
-<<dot>>=
-"PATTERN1" -> "PACKAGE" 
-"PatternFunctions1(a:SetCategory,b:Type)" -> "Package"
-@
-<<package PATTERN1 PatternFunctions1>>=
-)abbrev package PATTERN1 PatternFunctions1
-++ Utilities for handling patterns
-++ Author: Manuel Bronstein
-++ Date Created: 28 Nov 1989
-++ Date Last Updated: 5 Jul 1990
-++ Description: Tools for patterns;
-++ Keywords: pattern, matching.
-PatternFunctions1(R:SetCategory, D:Type): with
-    suchThat   : (Pattern R, D -> Boolean)       -> Pattern R
-      ++ suchThat(p, f) makes a copy of p and adds the predicate
-      ++ f to the copy, which is returned.
-    suchThat   : (Pattern R, List(D -> Boolean)) -> Pattern R
-      ++ \spad{suchThat(p, [f1,...,fn])} makes a copy of p and adds the
-      ++ predicate f1 and ... and fn to the copy, which is returned.
-    suchThat : (Pattern R, List Symbol, List D -> Boolean)  -> Pattern R
-      ++ \spad{suchThat(p, [a1,...,an], f)} returns a copy of p with
-      ++ the top-level predicate set to \spad{f(a1,...,an)}.
-    predicate  : Pattern R -> (D -> Boolean)
-      ++ predicate(p) returns the predicate attached to p, the
-      ++ constant function true if p has no predicates attached to it.
-    satisfy?   : (D, Pattern R) -> Boolean
-      ++ satisfy?(v, p) returns f(v) where f is the predicate
-      ++ attached to p.
-    satisfy?   : (List D, Pattern R) -> Boolean
-      ++ \spad{satisfy?([v1,...,vn], p)} returns \spad{f(v1,...,vn)} 
-      ++ where f is the
-      ++ top-level predicate attached to p.
-    addBadValue: (Pattern R, D) -> Pattern R
-      ++ addBadValue(p, v) adds v to the list of "bad values" for p;
-      ++ p is not allowed to match any of its "bad values".
-    badValues  : Pattern R -> List D
-      ++ badValues(p) returns the list of "bad values" for p;
-      ++ p is not allowed to match any of its "bad values".
-  == add
-    A1D ==> AnyFunctions1(D)
-    A1  ==> AnyFunctions1(D -> Boolean)
-    A1L ==> AnyFunctions1(List D -> Boolean)
- 
-    applyAll: (List Any, D) -> Boolean
-    st      : (Pattern R, List Any) -> Pattern R
- 
-    st(p, l)          == withPredicates(p, concat(predicates p, l))
-    predicate p       == applyAll(predicates p, #1)
-    addBadValue(p, v) == addBadValue(p, coerce(v)$A1D)
-    badValues p       == [retract(v)$A1D for v in getBadValues p]
-    suchThat(p, l, f) == setTopPredicate(copy p, l, coerce(f)$A1L)
-    suchThat(p:Pattern R, f:D -> Boolean) == st(p, [coerce(f)$A1])
-    satisfy?(d:D, p:Pattern R)            == applyAll(predicates p, d)
- 
-    satisfy?(l:List D, p:Pattern R) ==
-      empty?((rec := topPredicate p).var) => true
-      retract(rec.pred)$A1L l
- 
-    applyAll(l, d) ==
-      for f in l repeat
-        not(retract(f)$A1 d) => return false
-      true
- 
-    suchThat(p:Pattern R, l:List(D -> Boolean)) ==
-      st(p, [coerce(f)$A1 for f in l])
-
-@
-\section{package PATTERN2 PatternFunctions2}
-<<dot>>=
-"PATTERN2" -> "PACKAGE"
-"PatternFunctions2(a:SetCategory,b:SetCategory)" -> "Package"
-@
-<<package PATTERN2 PatternFunctions2>>=
-)abbrev package PATTERN2 PatternFunctions2
-++ Lifting of maps to patterns
-++ Author: Manuel Bronstein
-++ Date Created: 28 Nov 1989
-++ Date Last Updated: 12 Jan 1990
-++ Description: Lifts maps to patterns;
-++ Keywords: pattern, matching.
-PatternFunctions2(R:SetCategory, S:SetCategory): with
-    map: (R -> S, Pattern R) -> Pattern S
-      ++ map(f, p) applies f to all the leaves of p and
-      ++ returns the result as a pattern over S.
-  == add
-    map(f, p) ==
-      (r := (retractIfCan p)@Union(R, "failed")) case R =>
-        f(r::R)::Pattern(S)
-      (u := isOp p) case Record(op:BasicOperator, arg:List Pattern R) =>
-        ur := u::Record(op:BasicOperator, arg:List Pattern R)
-        (ur.op) [map(f, x) for x in ur.arg]
-      (v := isQuotient p) case Record(num:Pattern R, den:Pattern R) =>
-        vr := v::Record(num:Pattern R, den:Pattern R)
-        map(f, vr.num) / map(f, vr.den)
-      (l := isPlus p) case List(Pattern R) =>
-        reduce("+", [map(f, x) for x in l::List(Pattern R)])
-      (l := isTimes p) case List(Pattern R) =>
-        reduce("*", [map(f, x) for x in l::List(Pattern R)])
-      (x := isPower p) case
-       Record(val:Pattern R, exponent: Pattern R) =>
-        xr := x::Record(val:Pattern R, exponent: Pattern R)
-        map(f, xr.val) ** map(f, xr.exponent)
-      (w := isExpt p) case
-       Record(val:Pattern R, exponent: NonNegativeInteger) =>
-        wr := w::Record(val:Pattern R, exponent: NonNegativeInteger)
-        map(f, wr.val) ** wr.exponent
-      sy := retract(p)@Symbol
-      setPredicates(sy::Pattern(S), copy predicates 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 PATTERN1 PatternFunctions1>>
-<<package PATTERN2 PatternFunctions2>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pdecomp.spad.pamphlet b/src/algebra/pdecomp.spad.pamphlet
deleted file mode 100644
index 37057fc..0000000
--- a/src/algebra/pdecomp.spad.pamphlet
+++ /dev/null
@@ -1,135 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pdecomp.spad}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PCOMP PolynomialComposition}
-<<package PCOMP PolynomialComposition>>=
-)abbrev package PCOMP PolynomialComposition
-++ Description:
-++ This package \undocumented
-PolynomialComposition(UP: UnivariatePolynomialCategory(R), R: Ring): with
-        compose: (UP, UP) -> UP
-		++ compose(p,q) \undocumented
-    == add
-        compose(g, h) ==
-            r: UP := 0
-            while g ^= 0 repeat
-                r := leadingCoefficient(g)*h**degree(g) + r
-                g := reductum g
-            r
-
-@
-\section{package PDECOMP PolynomialDecomposition}
-<<package PDECOMP PolynomialDecomposition>>=
-)abbrev package PDECOMP PolynomialDecomposition
-++ Description:
-++ This package \undocumented
---  Ref: Kozen and Landau, Cornell University  TR 86-773
-PolynomialDecomposition(UP, F): PDcat == PDdef where
-    F:Field
-    UP:UnivariatePolynomialCategory F
-    NNI ==> NonNegativeInteger
-    LR  ==> Record(left: UP, right: UP)
- 
-    PDcat == with
-        decompose: UP -> List UP
-		++ decompose(up) \undocumented
-        decompose: (UP, NNI, NNI) -> Union(LR, "failed")
-		++ decompose(up,m,n) \undocumented
-        leftFactor: (UP, UP) -> Union(UP, "failed") 
-		++ leftFactor(p,q) \undocumented
-        rightFactorCandidate:  (UP, NNI) -> UP
-		++ rightFactorCandidate(p,n) \undocumented
-    PDdef == add
-        leftFactor(f, h) ==
-             g: UP := 0
-             for i in 0.. while f ^= 0 repeat
-                 fr := divide(f, h)
-                 f := fr.quotient; r := fr.remainder
-                 degree r > 0 => return "failed"
-                 g := g + r * monomial(1, i)
-             g
- 
-        decompose(f, dg, dh) ==
-            df := degree f
-            dg*dh ^= df => "failed"
-            h := rightFactorCandidate(f, dh)
-            g := leftFactor(f, h)
-            g case "failed" => "failed"
-            [g::UP, h]
- 
-        decompose f ==
-            df := degree f
-            for dh in 2..df-1 | df rem dh = 0 repeat
-                h := rightFactorCandidate(f, dh)
-                g := leftFactor(f, h)
-                g case UP => return
-                    append(decompose(g::UP), decompose h)
-            [f]
-        rightFactorCandidate(f, dh) ==
-            f  := f/leadingCoefficient f
-            df := degree f
-            dg := df quo dh
-            h  := monomial(1, dh)
-            for k in 1..dh repeat
-                hdg:= h**dg
-                c  := (coefficient(f,(df-k)::NNI)-coefficient(hdg,(df-k)::NNI))/(dg::F)
-                h  := h + monomial(c, (dh-k)::NNI)
-            h - monomial(coefficient(h, 0), 0) -- drop constant term
-
-@
-\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>>
- 
---% Polynomial composition and decomposition functions
---  If f = g o h then  g = leftFactor(f, h)  &  h = rightFactor(f, g)
---  SMW Dec 86
-
-<<package PCOMP PolynomialComposition>>
-<<package PDECOMP PolynomialDecomposition>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/perman.spad.pamphlet b/src/algebra/perman.spad.pamphlet
deleted file mode 100644
index 0e456a2..0000000
--- a/src/algebra/perman.spad.pamphlet
+++ /dev/null
@@ -1,396 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra perman.spad}
-\author{Johannes Grabmeier, Oswald Gschnitzer}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package GRAY GrayCode}
-<<package GRAY GrayCode>>=
-)abbrev package GRAY GrayCode
-++ Authors: Johannes Grabmeier, Oswald Gschnitzer
-++ Date Created: 7 August 1989
-++ Date Last Updated: 23 August 1990
-++ Basic Operations: nextSubsetGray
-++ Related Constructors: Permanent
-++ Also See: SymmetricGroupCombinatoric Functions
-++ AMS Classifications:
-++ Keywords: gray code, subsets of finite sets 
-++ References:
-++  Henryk Minc: Evaluation of Permanents,
-++    Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
-++  Nijenhuis and Wilf : Combinatorical Algorithms, Academic
-++    Press, New York 1978.
-++   S.G.Williamson, Combinatorics for Computer Science,
-++    Computer Science Press, 1985.
-++ Description:
-++  GrayCode provides a function for efficiently running
-++  through all subsets of a finite set, only changing one element
-++  by another one.
-GrayCode: public == private where
- 
-  PI ==> PositiveInteger
-  I  ==> Integer
-  V  ==> Vector
- 
-  public ==> with
- 
-    nextSubsetGray: (V V I,PI) -> V V I
-      ++ nextSubsetGray(ww,n) returns a vector {\em vv} whose components
-      ++ have the following meanings:\begin{items}
-      ++ \item {\em vv.1}: a vector of length n whose entries are 0 or 1. This
-      ++    can be interpreted as a code for a subset of the set 1,...,n;
-      ++    {\em vv.1} differs from {\em ww.1} by exactly one entry;
-      ++ \item {\em vv.2.1} is the number of the entry of {\em vv.1} which
-      ++    will be changed next time;
-      ++ \item {\em vv.2.1 = n+1} means that {\em vv.1} is the last subset;
-      ++    trying to compute nextSubsetGray(vv) if {\em vv.2.1 = n+1}
-      ++    will produce an error!
-      ++ \end{items}
-      ++ The other components of {\em vv.2} are needed to compute
-      ++ nextSubsetGray efficiently.
-      ++ Note: this is an implementation of [Williamson, Topic II, 3.54,
-      ++ p. 112] for the special case {\em r1 = r2 = ... = rn = 2};
-      ++ Note: nextSubsetGray produces a side-effect, i.e.
-      ++ {\em nextSubsetGray(vv)} and {\em vv := nextSubsetGray(vv)}
-      ++ will have the same effect.
- 
-    firstSubsetGray: PI -> V V I
-      ++ firstSubsetGray(n) creates the first vector {\em ww} to start a
-      ++ loop using {\em nextSubsetGray(ww,n)}
- 
-  private ==> add
- 
-    firstSubsetGray(n : PI) ==
-      vv : V V I := new(2,[])
-      vv.1 := new(n,0) : V I
-      vv.2 := new(n+1,1) : V I
-      for i in 1..(n+1) repeat
-        vv.2.i := i
-      vv
- 
-    nextSubsetGray(vv : V V I,n : PI) ==
-      subs : V I := vv.1    -- subset
-      lab : V I := vv.2     -- labels
-      c : I := lab(1)    -- element which is to be changed next
-      lab(1):= 1
-      if subs.c = 0 then subs.c := 1
-      else subs.c := 0
-      lab.c := lab(c+1)
-      lab(c+1) := c+1
-      vv
-
-@
-\section{package PERMAN Permanent}
-<<Permanent.input>>=
--- perman.spad.pamphlet Permanent.input
-)spool Permanent.output
-)set message test on
-)set message auto off
-)clear all
---S 1 of 3
-kn n ==
-  r : MATRIX INT := new(n,n,1)
-  for i in 1..n repeat
-    r.i.i := 0
-  r
---R 
---R                                                                   Type: Void
---E 1
-
---S 2 of 3
-permanent(kn(5) :: SQMATRIX(5,INT))
---R 
---R   Compiling function kn with type PositiveInteger -> Matrix Integer 
---R
---R   (2)  44
---R                                                        Type: PositiveInteger
---E 2
-
---S 3 of 3
-[permanent(kn(n) :: SQMATRIX(n,INT)) for n in 1..13]
---R 
---R   Cannot compile conversion for types involving local variables. In 
---R      particular, could not compile the expression involving :: 
---R      SQMATRIX(n,INT) 
---R   AXIOM will attempt to step through and interpret the code.
---R
---R   (3)
---R   [0,1,2,9,44,265,1854,14833,133496,1334961,14684570,176214841,2290792932]
---R                                                Type: List NonNegativeInteger
---E 3
-)spool
-)lisp (bye)
-@
-<<Permanent.help>>=
-====================================================================
-Permanent examples
-====================================================================
-
-The package Permanent provides the function permanent for square
-matrices.  The permanent of a square matrix can be computed in the
-same way as the determinant by expansion of minors except that for the
-permanent the sign for each element is 1, rather than being 1 if the
-row plus column indices is positive and -1 otherwise.  This function
-is much more difficult to compute efficiently than the determinant.
-An example of the use of permanent is the calculation of the n-th
-derangement number, defined to be the number of different possibilities 
-for n couples to dance but never with their own spouse.
-
-Consider an n by n matrix with entries 0 on the diagonal and 1 elsewhere.  
-Think of the rows as one-half of each couple (for example, the males) and 
-the columns the other half.  The permanent of such a matrix gives the 
-desired derangement number.
-
-  kn n ==
-    r : MATRIX INT := new(n,n,1)
-    for i in 1..n repeat
-      r.i.i := 0
-    r
-
-Here are some derangement numbers, which you see grow quite fast.
-
-  permanent(kn(5) :: SQMATRIX(5,INT))
-
-  [permanent(kn(n) :: SQMATRIX(n,INT)) for n in 1..13]
-
-See Also:
-o )show Permanent
-o $AXIOM/doc/src/algebra/perman.spad.dvi
-
-@
-<<package PERMAN Permanent>>=
-)abbrev package PERMAN Permanent
-++ Authors: Johannes Grabmeier, Oswald Gschnitzer
-++ Date Created: 7 August 1989
-++ Date Last Updated: 23 August 1990
-++ Basic Operations: permanent
-++ Related Constructors: GrayCode
-++ Also See: MatrixLinearAlgebraFunctions
-++ AMS Classifications:
-++ Keywords: permanent
-++ References:
-++  Henryk Minc: Evaluation of Permanents,
-++    Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
-++  Nijenhuis and Wilf : Combinatorical Algorithms, Academic
-++    Press, New York 1978.
-++  S.G.Williamson, Combinatorics for Computer Science,
-++    Computer Science Press, 1985.
-++ Description:
-++  Permanent implements the functions {\em permanent}, the 
-++  permanent for square matrices.
-Permanent(n : PositiveInteger, R : Ring with commutative("*")):
- public == private where
-  I  ==> Integer
-  L  ==> List
-  V  ==> Vector
-  SM  ==> SquareMatrix(n,R)
-  VECTPKG1 ==> VectorPackage1(I)
-  NNI ==> NonNegativeInteger
-  PI ==> PositiveInteger
-  GRAY ==> GrayCode
- 
-  public ==> with
- 
-    permanent:  SM  -> R
-      ++ permanent(x) computes the permanent of a square matrix x.
-      ++ The {\em permanent} is equivalent to 
-      ++ the \spadfun{determinant} except that coefficients have 
-      ++ no change of sign. This function
-      ++ is much more difficult to compute than the 
-      ++ {\em determinant}. The formula used is by H.J. Ryser,
-      ++ improved by [Nijenhuis and Wilf, Ch. 19].
-      ++ Note: permanent(x) choose one of three algorithms, depending
-      ++ on the underlying ring R and on n, the number of rows (and
-      ++ columns) of x:\begin{items}
-      ++ \item 1. if 2 has an inverse in R we can use the algorithm of
-      ++    [Nijenhuis and Wilf, ch.19,p.158]; if 2 has no inverse,
-      ++    some modifications are necessary:
-      ++ \item 2. if {\em n > 6} and R is an integral domain with characteristic
-      ++    different from 2 (the algorithm works if and only 2 is not a
-      ++    zero-divisor of R and {\em characteristic()$R ^= 2},
-      ++    but how to check that for any given R ?),
-      ++    the local function {\em permanent2} is called;
-      ++ \item 3. else, the local function {\em permanent3} is called
-      ++    (works for all commutative rings R).
-      ++ \end{items}
- 
-  private ==> add
- 
-    -- local functions:
- 
-    permanent2:  SM  -> R
- 
-    permanent3:  SM  -> R
- 
-    x : SM
-    a,b : R
-    i,j,k,l : I
- 
-    permanent3(x) ==
-      -- This algorithm is based upon the principle of inclusion-
-      -- exclusion. A Gray-code is used to generate the subsets of
-      -- 1,... ,n. This reduces the number of additions needed in
-      -- every step.
-      sgn : R := 1
-      k : R
-      a := 0$R
-      vv : V V I := firstSubsetGray(n)$GRAY
-        -- For the meaning of the elements of vv, see GRAY.
-      w : V R := new(n,0$R)
-      j := 1   -- Will be the number of the element changed in subset
-      while j ^= (n+1) repeat  -- we sum over all subsets of (1,...,n)
-        sgn := -sgn
-        b := sgn
-        if vv.1.j = 1 then k := -1
-        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
-        for i in 1..(n::I) repeat
-          w.i :=  w.i +$R k *$R  x(i,j)
-          b := b *$R w.i
-        a := a +$R b
-        vv := nextSubsetGray(vv,n)$GRAY
-        j := vv.2.1
-      if odd?(n) then a := -a
-      a
- 
- 
-    permanent(x) ==
-      -- If 2 has an inverse in R, we can spare half of the calcu-
-      -- lation needed in "permanent3": This is the algorithm of
-      -- [Nijenhuis and Wilf, ch.19,p.158]
-      n = 1 => x(1,1)
-      two : R := (2:I) :: R
-      half : Union(R,"failed") := recip(two)
-      if (half case "failed") then
-        if n < 7 then return permanent3(x)
-        else return permanent2(x)
-      sgn : R := 1
-      a := 0$R
-      w : V R := new(n,0$R)
-      -- w.i will be at first x.i and later lambda.i in
-      -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
-      rowi : V R := new(n,0$R)
-      for i in 1..n repeat
-        rowi := row(x,i) :: V R
-        b := 0$R
-        for j in 1..n repeat
-          b := b + rowi.j
-        w.i := rowi(n) - (half*b)$R
-      vv : V V I := firstSubsetGray((n-1): PI)$GRAY
-       -- For the meaning of the elements of vv, see GRAY.
-      n :: I
-      b := 1
-      for i in 1..n repeat
-        b := b * w.i
-      a := a+b
-      j := 1   -- Will be the number of the element changed in subset
-      while j ^= n repeat  -- we sum over all subsets of (1,...,n-1)
-        sgn := -sgn
-        b := sgn
-        if vv.1.j = 1 then k := -1
-        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
-        for i in 1..n repeat
-          w.i :=  w.i +$R k *$R  x(i,j)
-          b := b *$R w.i
-        a := a +$R b
-        vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
-        j := vv.2.1
-      if not odd?(n) then a := -a
-      two * a
- 
-    permanent2(x) ==
-      c : R := 0
-      sgn : R := 1
-      if (not (R has IntegralDomain))
-        -- or (characteristic()$R = (2:NNI))
-        -- compiler refuses to compile the line above !!
-        or  (sgn + sgn = c)
-      then return permanent3(x)
-      -- This is a slight modification of permanent which is
-      -- necessary if 2 is not zero or a zero-divisor in R, but has
-      -- no inverse in R.
-      n = 1 => x(1,1)
-      two : R := (2:I) :: R
-      a := 0$R
-      w : V R := new(n,0$R)
-      -- w.i will be at first x.i and later lambda.i in
-      -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
-      rowi : V R := new(n,0$R)
-      for i in 1..n repeat
-        rowi := row(x,i) :: V R
-        b := 0$R
-        for j in 1..n repeat
-          b := b + rowi.j
-        w.i := (two*(rowi(n)))$R - b
-      vv : V V I := firstSubsetGray((n-1): PI)$GRAY
-      n :: I
-      b := 1
-      for i in 1..n repeat
-        b := b *$R w.i
-      a := a +$R b
-      j := 1   -- Will be the number of the element changed in subset
-      while j ^= n repeat  -- we sum over all subsets of (1,...,n-1)
-        sgn := -sgn
-        b := sgn
-        if vv.1.j = 1 then k := -1
-        else k := 1  -- was that element deleted(k=-1) or added(k=1)?
-        c := k * two
-        for i in 1..n repeat
-          w.i :=  w.i +$R c *$R x(i,j)
-          b := b *$R w.i
-        a := a +$R b
-        vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
-        j := vv.2.1
-      if not odd?(n) then a := -a
-      b := two ** ((n-1):NNI)
-      (a exquo b) :: R
-
-@
-\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 GRAY GrayCode>>
-<<package PERMAN Permanent>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/permgrps.spad.pamphlet b/src/algebra/permgrps.spad.pamphlet
deleted file mode 100644
index af5af2c..0000000
--- a/src/algebra/permgrps.spad.pamphlet
+++ /dev/null
@@ -1,428 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra permgrps.spad}
-\author{Gerhard Schneider, Holger Gollan, Johannes Grabmeier, M. Weller}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PGE PermutationGroupExamples}
-<<package PGE PermutationGroupExamples>>=
-)abbrev package PGE PermutationGroupExamples
-++ Authors: M. Weller, G. Schneider, J. Grabmeier
-++ Date Created: 20 February 1990
-++ Date Last Updated: 09 June 1990
-++ Basic Operations:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++  J. Conway, R. Curtis, S. Norton, R. Parker, R. Wilson:
-++   Atlas of Finite Groups, Oxford, Clarendon Press, 1987
-++ Description: 
-++   PermutationGroupExamples provides permutation groups for
-++   some classes of groups: symmetric, alternating, dihedral, cyclic,
-++   direct products of cyclic, which are in fact the finite abelian groups
-++   of symmetric groups called Young subgroups.
-++   Furthermore, Rubik's group as permutation group of 48 integers and a list
-++   of sporadic simple groups derived from the atlas of finite groups.
-
-PermutationGroupExamples():public == private where
-
-    L          ==> List
-    I          ==> Integer
-    PI         ==> PositiveInteger
-    NNI        ==> NonNegativeInteger
-    PERM       ==> Permutation
-    PERMGRP   ==> PermutationGroup
-
-    public ==> with
-
-      symmetricGroup:       PI        -> PERMGRP I
-        ++ symmetricGroup(n) constructs the symmetric group {\em Sn}
-        ++ acting on the integers 1,...,n, generators are the
-        ++ {\em n}-cycle {\em (1,...,n)} and the 2-cycle {\em (1,2)}.
-      symmetricGroup:       L I       -> PERMGRP I
-        ++ symmetricGroup(li) constructs the symmetric group acting on
-        ++ the integers in the list {\em li}, generators are the
-        ++ cycle given by {\em li} and the 2-cycle {\em (li.1,li.2)}.
-        ++ Note: duplicates in the list will be removed.
-      alternatingGroup:     PI        -> PERMGRP I
-        ++ alternatingGroup(n) constructs the alternating group {\em An}
-        ++ acting on the integers 1,...,n,  generators are in general the
-        ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
-        ++ if n is odd and the product of the 2-cycle {\em (1,2)} with
-        ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
-        ++ if n is even.
-      alternatingGroup:     L I       -> PERMGRP I
-        ++ alternatingGroup(li) constructs the alternating group acting
-        ++ on the integers in the list {\em li}, generators are in general the
-        ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
-        ++ {\em (li.1,li.2,li.3)}, if n is odd and
-        ++ product of the 2-cycle {\em (li.1,li.2)} with
-        ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
-        ++ {\em (li.1,li.2,li.3)}, if n is even.
-        ++ Note: duplicates in the list will be removed.
-      abelianGroup:         L PI      -> PERMGRP I
-        ++ abelianGroup([n1,...,nk]) constructs the abelian group that
-        ++ is the direct product of cyclic groups with order {\em ni}.
-      cyclicGroup:          PI        -> PERMGRP I
-        ++ cyclicGroup(n) constructs the cyclic group of order n acting
-        ++ on the integers 1,...,n.
-      cyclicGroup:          L I       -> PERMGRP I
-        ++ cyclicGroup([i1,...,ik]) constructs the cyclic group of
-        ++ order k acting on the integers {\em i1},...,{\em ik}.
-        ++ Note: duplicates in the list will be removed.
-      dihedralGroup:        PI        -> PERMGRP I
-        ++ dihedralGroup(n) constructs the dihedral group of order 2n
-        ++ acting on integers 1,...,N.
-      dihedralGroup:        L I       -> PERMGRP I
-        ++ dihedralGroup([i1,...,ik]) constructs the dihedral group of
-        ++ order 2k acting on the integers out of {\em i1},...,{\em ik}.
-        ++ Note: duplicates in the list will be removed.
-      mathieu11:            L I       -> PERMGRP I
-        ++ mathieu11(li) constructs the mathieu group acting on the 11
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed.
-        ++ error, if {\em li} has less or more than 11 different entries.
-      mathieu11:            ()        -> PERMGRP I
-        ++ mathieu11 constructs the mathieu group acting on the
-        ++ integers 1,...,11.
-      mathieu12:            L I       -> PERMGRP I
-        ++ mathieu12(li) constructs the mathieu group acting on the 12
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed
-        ++ Error: if {\em li} has less or more than 12 different entries.
-      mathieu12:            ()        -> PERMGRP I
-        ++ mathieu12 constructs the mathieu group acting on the
-        ++ integers 1,...,12.
-      mathieu22:            L I       -> PERMGRP I
-        ++ mathieu22(li) constructs the mathieu group acting on the 22
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed.
-        ++ Error: if {\em li} has less or more than 22 different entries.
-      mathieu22:            ()        -> PERMGRP I
-        ++ mathieu22 constructs the mathieu group acting on the
-        ++ integers 1,...,22.
-      mathieu23:            L I       -> PERMGRP I
-        ++ mathieu23(li) constructs the mathieu group acting on the 23
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed.
-        ++ Error: if {\em li} has less or more than 23 different entries.
-      mathieu23:            ()        -> PERMGRP I
-        ++ mathieu23 constructs the mathieu group acting on the
-        ++ integers 1,...,23.
-      mathieu24:            L I       -> PERMGRP I
-        ++ mathieu24(li) constructs the mathieu group acting on the 24
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed.
-        ++ Error: if {\em li} has less or more than 24 different entries.
-      mathieu24:            ()        -> PERMGRP I
-        ++ mathieu24 constructs the mathieu group acting on the
-        ++ integers 1,...,24.
-      janko2:               L I       -> PERMGRP I
-        ++ janko2(li) constructs the janko group acting on the 100
-        ++ integers given in the list {\em li}.
-        ++ Note: duplicates in the list will be removed.
-        ++ Error: if {\em li} has less or more than 100 different entries
-      janko2:               ()        -> PERMGRP I
-        ++ janko2 constructs the janko group acting on the
-        ++ integers 1,...,100.
-      rubiksGroup:          ()        -> PERMGRP I
-        ++ rubiksGroup constructs the permutation group representing
-        ++ Rubic's Cube acting on integers {\em 10*i+j} for
-        ++ {\em 1 <= i <= 6}, {\em 1 <= j <= 8}.
-        ++ The faces of Rubik's Cube are labelled in the obvious way
-        ++ Front, Right, Up, Down, Left, Back and numbered from 1 to 6
-        ++ in this given ordering, the pieces on each face
-        ++ (except the unmoveable center piece) are clockwise numbered
-        ++ from 1 to 8 starting with the piece in the upper left
-        ++ corner. The moves of the cube are represented as permutations
-        ++ on these pieces, represented as a two digit
-        ++ integer {\em ij} where i is the numer of theface (1 to 6)
-        ++ and j is the number of the piece on this face.
-        ++ The remaining ambiguities are resolved by looking
-        ++ at the 6 generators, which represent a 90 degree turns of the
-        ++ faces, or from the following pictorial description.
-        ++ Permutation group representing Rubic's Cube acting on integers
-        ++ 10*i+j for 1 <= i <= 6, 1 <= j <=8.
-        ++
-        ++ \begin{verbatim}
-        ++ Rubik's Cube:   +-----+ +-- B   where: marks Side # :
-        ++                / U   /|/
-        ++               /     / |         F(ront)    <->    1
-        ++       L -->  +-----+ R|         R(ight)    <->    2
-        ++              |     |  +         U(p)       <->    3
-        ++              |  F  | /          D(own)     <->    4
-        ++              |     |/           L(eft)     <->    5
-        ++              +-----+            B(ack)     <->    6
-        ++                 ^
-        ++                 |
-        ++                 D
-        ++
-        ++ The Cube's surface:
-        ++                                The pieces on each side
-        ++             +---+              (except the unmoveable center
-        ++             |567|              piece) are clockwise numbered
-        ++             |4U8|              from 1 to 8 starting with the
-        ++             |321|              piece in the upper left
-        ++         +---+---+---+          corner (see figure on the
-        ++         |781|123|345|          left).  The moves of the cube
-        ++         |6L2|8F4|2R6|          are represented as
-        ++         |543|765|187|          permutations on these pieces.
-        ++         +---+---+---+          Each of the pieces is
-        ++             |123|              represented as a two digit
-        ++             |8D4|              integer ij where i is the
-        ++             |765|              # of the side ( 1 to 6 for
-        ++             +---+              F to B (see table above ))
-        ++             |567|              and j is the # of the piece.
-        ++             |4B8|
-        ++             |321|
-        ++             +---+
-        ++ \end{verbatim}
-      youngGroup:           L I      -> PERMGRP I
-        ++ youngGroup([n1,...,nk]) constructs the direct product of the
-        ++ symmetric groups {\em Sn1},...,{\em Snk}.
-      youngGroup:    Partition        -> PERMGRP I
-        ++ youngGroup(lambda) constructs the direct product of the symmetric
-        ++ groups given by the parts of the partition {\em lambda}.
-
-    private ==> add
-
-      -- import the permutation and permutation group domains:
-
-      import PERM I
-      import PERMGRP I
-
-      -- import the needed map function:
-
-      import ListFunctions2(L L I,PERM I)
-      -- the internal functions:
-
-      llli2gp(l:L L L I):PERMGRP I ==
-        --++ Converts an list of permutations each represented by a list
-        --++ of cycles ( each of them represented as a list of Integers )
-        --++ to the permutation group generated by these permutations.
-        (map(cycles,l))::PERMGRP I
-
-      li1n(n:I):L I ==
-        --++ constructs the list of integers from 1 to n
-        [i for i in 1..n]
-
-      -- definition of the exported functions:
-      youngGroup(l:L I):PERMGRP I ==
-        gens:= nil()$(L L L I)
-        element:I:= 1
-        for n in l | n > 1 repeat
-          gens:=cons(list [i for i in element..(element+n-1)], gens)
-          if n >= 3 then gens := cons([[element,element+1]],gens)
-          element:=element+n
-        llli2gp
-          #gens = 0 => [[[1]]]
-          gens
-
-      youngGroup(lambda : Partition):PERMGRP I ==
-        youngGroup(convert(lambda)$Partition)
-
-      rubiksGroup():PERMGRP I ==
-        -- each generator represents a 90 degree turn of the appropriate
-        -- side.
-        f:L L I:=
-         [[11,13,15,17],[12,14,16,18],[51,31,21,41],[53,33,23,43],[52,32,22,42]]
-        r:L L I:=
-         [[21,23,25,27],[22,24,26,28],[13,37,67,43],[15,31,61,45],[14,38,68,44]]
-        u:L L I:=
-         [[31,33,35,37],[32,34,36,38],[13,51,63,25],[11,57,61,23],[12,58,62,24]]
-        d:L L I:=
-         [[41,43,45,47],[42,44,46,48],[17,21,67,55],[15,27,65,53],[16,28,66,54]]
-        l:L L I:=
-         [[51,53,55,57],[52,54,56,58],[11,41,65,35],[17,47,63,33],[18,48,64,34]]
-        b:L L I:=
-         [[61,63,65,67],[62,64,66,68],[45,25,35,55],[47,27,37,57],[46,26,36,56]]
-        llli2gp [f,r,u,d,l,b]
-
-      mathieu11(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 11 => error "Exactly 11 integers for mathieu11 needed !"
-        a:L L I:=[[l.1,l.10],[l.2,l.8],[l.3,l.11],[l.5,l.7]]
-        llli2gp [a,[[l.1,l.4,l.7,l.6],[l.2,l.11,l.10,l.9]]]
-
-      mathieu11():PERMGRP I == mathieu11 li1n 11
-
-      mathieu12(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 12 => error "Exactly 12 integers for mathieu12 needed !"
-        a:L L I:=
-          [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11]]
-        llli2gp [a,[[l.1,l.6,l.5,l.8,l.3,l.7,l.4,l.2,l.9,l.10],[l.11,l.12]]]
-
-      mathieu12():PERMGRP I == mathieu12 li1n 12
-
-      mathieu22(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 22 => error "Exactly 22 integers for mathieu22 needed !"
-        a:L L I:=[[l.1,l.2,l.4,l.8,l.16,l.9,l.18,l.13,l.3,l.6,l.12],   _
-          [l.5,l.10,l.20,l.17,l.11,l.22,l.21,l.19,l.15,l.7,l.14]]
-        b:L L I:= [[l.1,l.2,l.6,l.18],[l.3,l.15],[l.5,l.8,l.21,l.13],   _
-          [l.7,l.9,l.20,l.12],[l.10,l.16],[l.11,l.19,l.14,l.22]]
-        llli2gp [a,b]
-
-      mathieu22():PERMGRP I == mathieu22 li1n 22
-
-      mathieu23(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 23 => error "Exactly 23 integers for mathieu23 needed !"
-        a:L L I:= [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11,l.12,l.13,l.14,_
-                   l.15,l.16,l.17,l.18,l.19,l.20,l.21,l.22,l.23]]
-        b:L L I:= [[l.2,l.16,l.9,l.6,l.8],[l.3,l.12,l.13,l.18,l.4],              _
-                   [l.7,l.17,l.10,l.11,l.22],[l.14,l.19,l.21,l.20,l.15]]
-        llli2gp [a,b]
-
-      mathieu23():PERMGRP I == mathieu23 li1n 23
-
-      mathieu24(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 24 => error "Exactly 24 integers for mathieu24 needed !"
-        a:L L I:= [[l.1,l.16,l.10,l.22,l.24],[l.2,l.12,l.18,l.21,l.7],          _
-                   [l.4,l.5,l.8,l.6,l.17],[l.9,l.11,l.13,l.19,l.15]]
-        b:L L I:= [[l.1,l.22,l.13,l.14,l.6,l.20,l.3,l.21,l.8,l.11],[l.2,l.10],  _
-                   [l.4,l.15,l.18,l.17,l.16,l.5,l.9,l.19,l.12,l.7],[l.23,l.24]]
-        llli2gp [a,b]
-
-      mathieu24():PERMGRP I == mathieu24 li1n 24
-
-      janko2(l:L I):PERMGRP I ==
-      -- permutations derived from the ATLAS
-        l:=removeDuplicates l
-        #l ^= 100 => error "Exactly 100 integers for janko2 needed !"
-        a:L L I:=[                                                            _
-                 [l.2,l.3,l.4,l.5,l.6,l.7,l.8],                               _
-                 [l.9,l.10,l.11,l.12,l.13,l.14,l.15],                         _
-                 [l.16,l.17,l.18,l.19,l.20,l.21,l.22],                        _
-                 [l.23,l.24,l.25,l.26,l.27,l.28,l.29],                        _
-                 [l.30,l.31,l.32,l.33,l.34,l.35,l.36],                        _
-                 [l.37,l.38,l.39,l.40,l.41,l.42,l.43],                        _
-                 [l.44,l.45,l.46,l.47,l.48,l.49,l.50],                        _
-                 [l.51,l.52,l.53,l.54,l.55,l.56,l.57],                        _
-                 [l.58,l.59,l.60,l.61,l.62,l.63,l.64],                        _
-                 [l.65,l.66,l.67,l.68,l.69,l.70,l.71],                        _
-                 [l.72,l.73,l.74,l.75,l.76,l.77,l.78],                        _
-                 [l.79,l.80,l.81,l.82,l.83,l.84,l.85],                        _
-                 [l.86,l.87,l.88,l.89,l.90,l.91,l.92],                        _
-                 [l.93,l.94,l.95,l.96,l.97,l.98,l.99] ]
-        b:L L I:=[
-                [l.1,l.74,l.83,l.21,l.36,l.77,l.44,l.80,l.64,l.2,l.34,l.75,l.48,l.17,l.100],_
-                [l.3,l.15,l.31,l.52,l.19,l.11,l.73,l.79,l.26,l.56,l.41,l.99,l.39,l.84,l.90],_
-                [l.4,l.57,l.86,l.63,l.85,l.95,l.82,l.97,l.98,l.81,l.8,l.69,l.38,l.43,l.58],_
-                [l.5,l.66,l.49,l.59,l.61],_
-                [l.6,l.68,l.89,l.94,l.92,l.20,l.13,l.54,l.24,l.51,l.87,l.27,l.76,l.23,l.67],_
-                [l.7,l.72,l.22,l.35,l.30,l.70,l.47,l.62,l.45,l.46,l.40,l.28,l.65,l.93,l.42],_
-                [l.9,l.71,l.37,l.91,l.18,l.55,l.96,l.60,l.16,l.53,l.50,l.25,l.32,l.14,l.33],_
-                [l.10,l.78,l.88,l.29,l.12] ]
-        llli2gp [a,b]
-
-      janko2():PERMGRP I == janko2 li1n 100
-
-      abelianGroup(l:L PI):PERMGRP I ==
-        gens:= nil()$(L L L I)
-        element:I:= 1
-        for n in l | n > 1 repeat
-          gens:=cons( list [i for i in element..(element+n-1) ], gens )
-          element:=element+n
-        llli2gp
-          #gens = 0 => [[[1]]]
-          gens
-
-      alternatingGroup(l:L I):PERMGRP I ==
-        l:=removeDuplicates l
-        #l = 0 =>
-          error "Cannot construct alternating group on empty set"
-        #l < 3 => llli2gp [[[l.1]]]
-        #l = 3 => llli2gp [[[l.1,l.2,l.3]]]
-        tmp:= [l.i for i in 3..(#l)]
-        gens:L L L I:=[[tmp],[[l.1,l.2,l.3]]]
-        odd?(#l) => llli2gp gens
-        gens.1 := cons([l.1,l.2],gens.1)
-        llli2gp gens
-
-      alternatingGroup(n:PI):PERMGRP I == alternatingGroup li1n n
-
-      symmetricGroup(l:L I):PERMGRP I ==
-        l:=removeDuplicates l
-        #l = 0 => error "Cannot construct symmetric group on empty set !"
-        #l < 3 => llli2gp [[l]]
-        llli2gp [[l],[[l.1,l.2]]]
-
-      symmetricGroup(n:PI):PERMGRP I == symmetricGroup li1n n
-
-      cyclicGroup(l:L I):PERMGRP I ==
-        l:=removeDuplicates l
-        #l = 0 => error "Cannot construct cyclic group on empty set"
-        llli2gp [[l]]
-
-      cyclicGroup(n:PI):PERMGRP I == cyclicGroup li1n n
-
-      dihedralGroup(l:L I):PERMGRP I ==
-        l:=removeDuplicates l
-        #l < 3 => error "in dihedralGroup: Minimum of 3 elements needed !"
-        tmp := [[l.i, l.(#l-i+1) ] for i in 1..(#l quo 2)]
-        llli2gp [ [ l ], tmp ]
-
-      dihedralGroup(n:PI):PERMGRP I ==
-        n = 1 => symmetricGroup (2::PI)
-        n = 2 => llli2gp [[[1,2]],[[3,4]]]
-        dihedralGroup li1n n
-
-@
-\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 PGE PermutationGroupExamples>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pfbr.spad.pamphlet b/src/algebra/pfbr.spad.pamphlet
deleted file mode 100644
index fd3b990..0000000
--- a/src/algebra/pfbr.spad.pamphlet
+++ /dev/null
@@ -1,591 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pfbr.spad}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PFBRU PolynomialFactorizationByRecursionUnivariate}
-<<package PFBRU PolynomialFactorizationByRecursionUnivariate>>=
-)abbrev package PFBRU PolynomialFactorizationByRecursionUnivariate
-++ PolynomialFactorizationByRecursionUnivariate
-++ R is a \spadfun{PolynomialFactorizationExplicit} domain,
-++ S is univariate polynomials over R
-++ We are interested in handling SparseUnivariatePolynomials over
-++ S, is a variable we shall call z
-PolynomialFactorizationByRecursionUnivariate(R, S): public == private where
-  R:PolynomialFactorizationExplicit
-  S:UnivariatePolynomialCategory(R)
-  PI ==> PositiveInteger
-  SupR ==> SparseUnivariatePolynomial R
-  SupSupR ==> SparseUnivariatePolynomial SupR
-  SupS ==> SparseUnivariatePolynomial S
-  SupSupS ==> SparseUnivariatePolynomial SupS
-  LPEBFS ==> LinearPolynomialEquationByFractions(S)
-  public ==  with
-     solveLinearPolynomialEquationByRecursion: (List SupS, SupS)  ->
-                                               Union(List SupS,"failed")
-        ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
-        ++ returns the list of polynomials \spad{[q1,...,qn]}
-        ++ such that \spad{sum qi/pi = p / prod pi}, a
-        ++ recursion step for solveLinearPolynomialEquation
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{solveLinearPolynomialEquation}).
-        ++ If no such list of qi exists, then "failed" is returned.
-     factorByRecursion:  SupS -> Factored SupS
-        ++ factorByRecursion(p) factors polynomial p. This function
-        ++ performs the recursion step for factorPolynomial,
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{factorPolynomial})
-     factorSquareFreeByRecursion:  SupS -> Factored SupS
-        ++ factorSquareFreeByRecursion(p) returns the square free
-        ++ factorization of p. This functions performs
-        ++ the recursion step for factorSquareFreePolynomial,
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{factorSquareFreePolynomial}).
-     randomR: -> R  -- has to be global, since has alternative definitions
-        ++ randomR() produces a random element of R
-     factorSFBRlcUnit: (SupS) -> Factored SupS
-        ++ factorSFBRlcUnit(p) returns the square free factorization of
-        ++ polynomial p
-        ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
-        ++ in the case where the leading coefficient of p
-        ++ is a unit.
-  private  == add
-   supR: SparseUnivariatePolynomial R
-   pp: SupS
-   lpolys,factors: List SupS
-   r:R
-   lr:List R
-   import FactoredFunctionUtilities(SupS)
-   import FactoredFunctions2(SupR,SupS)
-   import FactoredFunctions2(S,SupS)
-   import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
-   import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
-   -- local function declarations
-   raise: SupR -> SupS
-   lower: SupS -> SupR
-   factorSFBRlcUnitInner: (SupS,R) -> Union(Factored SupS,"failed")
-   hensel: (SupS,R,List SupS) ->
-           Union(Record(fctrs:List SupS),"failed")
-   chooseFSQViableSubstitutions: (SupS) ->
-    Record(substnsField:R,ppRField:SupR)
-     --++ chooseFSQViableSubstitutions(p), p is a sup
-     --++ ("sparse univariate polynomial")
-     --++ over a sup over R, returns a record
-     --++ \spad{[substnsField: r, ppRField: q]} where r is a substitution point
-     --++ q is a sup over R so that the (implicit) variable in q
-     --++ does not drop in degree and remains square-free.
-   -- here for the moment, until it compiles
-   -- N.B., we know that R is NOT a FiniteField, since
-   -- that is meant to have a special implementation, to break the
-   -- recursion
-   solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
-     lhsdeg:="max"/["max"/[degree v for v in coefficients u] for u in lpolys]
-     rhsdeg:="max"/[degree v for v in coefficients pp]
-     lhsdeg = 0 =>
-       lpolysLower:=[lower u for u in lpolys]
-       answer:List SupS := [0 for u in lpolys]
-       for i in 0..rhsdeg repeat
-         ppx:=map(coefficient(#1,i),pp)
-         zero? ppx => "next"
-         recAns:= solveLinearPolynomialEquation(lpolysLower,ppx)
-         recAns case "failed" => return "failed"
-         answer:=[monomial(1,i)$S * raise c + d
-                    for c in recAns for d in answer]
-       answer
-     solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
-   -- local function definitions
-   hensel(pp,r,factors) ==
-      -- factors is a relatively prime factorization of pp modulo the ideal
-      -- (x-r), with suitably imposed leading coefficients.
-      -- This is lifted, without re-combinations, to a factorization
-      -- return "failed" if this can't be done
-      origFactors:=factors
-      totdegree:Integer:=0
-      proddegree:Integer:=
-                   "max"/[degree(u) for u in coefficients pp]
-      n:PI:=1
-      pn:=prime:=monomial(1,1) - r::S
-      foundFactors:List SupS:=empty()
-      while (totdegree <= proddegree) repeat
-          Ecart:=(pp-*/factors) exquo  pn
-          Ecart case "failed" =>
-                error "failed lifting in hensel in PFBRU"
-          zero? Ecart =>
-             -- then we have all the factors
-             return [append(foundFactors, factors)]
-          step:=solveLinearPolynomialEquation(origFactors,
-                                              map(elt(#1,r::S),
-                                                  Ecart))
-          step case "failed" => return "failed" -- must be a false split
-          factors:=[a+b*pn for a in factors for b in step]
-          for a in factors for c in origFactors repeat
-              pp1:= pp exquo a
-              pp1 case "failed" => "next"
-              pp:=pp1
-              proddegree := proddegree - "max"/[degree(u)
-                                                for u in coefficients a]
-              factors:=remove(a,factors)
-              origFactors:=remove(c,origFactors)
-              foundFactors:=[a,:foundFactors]
-          #factors < 2 =>
-             return [(empty? factors => foundFactors;
-                                     [pp,:foundFactors])]
-          totdegree:= +/["max"/[degree(u)
-                                for u in coefficients u1]
-                         for u1 in factors]
-          n:=n+1
-          pn:=pn*prime
-      "failed" -- must have been a false split
-   chooseFSQViableSubstitutions(pp) ==
-     substns:R
-     ppR: SupR
-     while true repeat
-        substns:= randomR()
-        zero? elt(leadingCoefficient pp,substns ) => "next"
-        ppR:=map( elt(#1,substns),pp)
-        degree gcd(ppR,differentiate ppR)>0 => "next"
-        leave
-     [substns,ppR]
-   raise(supR) == map(#1:R::S,supR)
-   lower(pp) == map(retract(#1)::R,pp)
-   factorSFBRlcUnitInner(pp,r) ==
-      -- pp is square-free as a Sup, but the Up  variable occurs.
-      -- Furthermore, its LC is a unit
-      -- returns "failed" if the substitution is bad, else a factorization
-      ppR:=map(elt(#1,r),pp)
-      degree ppR < degree pp => "failed"
-      degree gcd(ppR,differentiate ppR) >0 => "failed"
-      factors:=
-        fDown:=factorSquareFreePolynomial ppR
-        [raise (unit fDown * factorList(fDown).first.fctr),
-         :[raise u.fctr for u in factorList(fDown).rest]]
-      #factors = 1 => makeFR(1,[["irred",pp,1]])
-      hen:=hensel(pp,r,factors)
-      hen case "failed" => "failed"
-      makeFR(1,[["irred",u,1] for u in hen.fctrs])
-   -- exported function definitions
-   if R has StepThrough then
-     factorSFBRlcUnit(pp) ==
-       val:R := init()
-       while true repeat
-          tempAns:=factorSFBRlcUnitInner(pp,val)
-          not (tempAns case "failed") => return tempAns
-          val1:=nextItem val
-          val1 case "failed" =>
-            error "at this point, we know we have a finite field"
-          val:=val1
-   else
-     factorSFBRlcUnit(pp) ==
-       val:R := randomR()
-       while true repeat
-          tempAns:=factorSFBRlcUnitInner(pp,val)
-          not (tempAns case "failed") => return tempAns
-          val := randomR()
-   if R has StepThrough then
-      randomCount:R:= init()
-      randomR() ==
-        v:=nextItem(randomCount)
-        v case "failed" =>
-          SAY$Lisp "Taking another set of random values"
-          randomCount:=init()
-          randomCount
-        randomCount:=v
-        randomCount
-   else if R has random: -> R then
-      randomR() == random()
-   else randomR() == (random()$Integer rem 100)::R
-   factorByRecursion pp ==
-     and/[zero? degree u for u in coefficients pp] =>
-         map(raise,factorPolynomial lower pp)
-     c:=content pp
-     unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
-     pp:=(pp exquo c)::SupS
-     mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
-                  map(#1:S::SupS,factor(c)$S))
-   factorSquareFreeByRecursion pp ==
-     and/[zero? degree u for u in coefficients pp] =>
-        map(raise,factorSquareFreePolynomial lower pp)
-     unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(pp)
-     oldnfact:NonNegativeInteger:= 999999
-                       -- I hope we never have to factor a polynomial
-                       -- with more than this number of factors
-     lcppPow:S
-     while true repeat  -- a loop over possible false splits
-       cVS:=chooseFSQViableSubstitutions(pp)
-       newppR:=primitivePart cVS.ppRField
-       factorsR:=factorSquareFreePolynomial(newppR)
-       (nfact:=numberOfFactors factorsR) = 1 =>
-                  return makeFR(1,[["irred",pp,1]])
-       -- OK, force all leading coefficients to be equal to the leading
-       -- coefficient of the input
-       nfact > oldnfact => "next"   -- can't be a good reduction
-       oldnfact:=nfact
-       lcppR:=leadingCoefficient cVS.ppRField
-       factors:=[raise((lcppR exquo leadingCoefficient u.fctr) ::R * u.fctr)
-                  for u in factorList factorsR]
-       -- factors now multiplies to give cVS.ppRField * lcppR^(#factors-1)
-       -- Now change the leading coefficient to be lcpp
-       factors:=[monomial(lcpp,degree u) + reductum u for u in factors]
---     factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
---                for u in factorList factorsR]
-       ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
-       OK:=true
-       hen:=hensel(ppAdjust,cVS.substnsField,factors)
-       hen case "failed" => "next"
-       factors:=hen.fctrs
-       leave
-     factors:=[ (lc:=content w;
-                 lcppPow:=(lcppPow exquo lc)::S;
-                  (w exquo lc)::SupS)
-                for w in factors]
-     not unit? lcppPow =>
-         error "internal error in factorSquareFreeByRecursion"
-     makeFR((recip lcppPow)::S::SupS,
-             [["irred",w,1] for w in factors])
-
-@
-\section{package PFBR PolynomialFactorizationByRecursion}
-<<package PFBR PolynomialFactorizationByRecursion>>=
-)abbrev package PFBR PolynomialFactorizationByRecursion
-++ Description: PolynomialFactorizationByRecursion(R,E,VarSet,S)
-++ is used for factorization of sparse univariate polynomials over
-++ a domain S of multivariate polynomials over R.
-PolynomialFactorizationByRecursion(R,E, VarSet:OrderedSet, S): public ==
- private where
-  R:PolynomialFactorizationExplicit
-  E:OrderedAbelianMonoidSup
-  S:PolynomialCategory(R,E,VarSet)
-  PI ==> PositiveInteger
-  SupR ==> SparseUnivariatePolynomial R
-  SupSupR ==> SparseUnivariatePolynomial SupR
-  SupS ==> SparseUnivariatePolynomial S
-  SupSupS ==> SparseUnivariatePolynomial SupS
-  LPEBFS ==> LinearPolynomialEquationByFractions(S)
-  public ==  with
-     solveLinearPolynomialEquationByRecursion: (List SupS, SupS)  ->
-                                                Union(List SupS,"failed")
-        ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
-        ++ returns the list of polynomials \spad{[q1,...,qn]}
-        ++ such that \spad{sum qi/pi = p / prod pi}, a
-        ++ recursion step for solveLinearPolynomialEquation
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{solveLinearPolynomialEquation}).
-        ++ If no such list of qi exists, then "failed" is returned.
-     factorByRecursion:  SupS -> Factored SupS
-        ++ factorByRecursion(p) factors polynomial p. This function
-        ++ performs the recursion step for factorPolynomial,
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{factorPolynomial})
-     factorSquareFreeByRecursion:  SupS -> Factored SupS
-        ++ factorSquareFreeByRecursion(p) returns the square free
-        ++ factorization of p. This functions performs
-        ++ the recursion step for factorSquareFreePolynomial,
-        ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
-        ++ (see \spadfun{factorSquareFreePolynomial}).
-     randomR: -> R  -- has to be global, since has alternative definitions
-        ++ randomR produces a random element of R
-     bivariateSLPEBR: (List SupS, SupS,  VarSet)  -> Union(List SupS,"failed")
-        ++ bivariateSLPEBR(lp,p,v) implements
-        ++ the bivariate case of
-        ++ \spadfunFrom{solveLinearPolynomialEquationByRecursion}{PolynomialFactorizationByRecursionUnivariate};
-        ++ its implementation depends on R
-     factorSFBRlcUnit: (List VarSet, SupS) -> Factored SupS
-        ++ factorSFBRlcUnit(p) returns the square free factorization of
-        ++ polynomial p
-        ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
-        ++ in the case where the leading coefficient of p
-        ++ is a unit.
-  private  == add
-   supR: SparseUnivariatePolynomial R
-   pp: SupS
-   lpolys,factors: List SupS
-   vv:VarSet
-   lvpolys,lvpp: List VarSet
-   r:R
-   lr:List R
-   import FactoredFunctionUtilities(SupS)
-   import FactoredFunctions2(S,SupS)
-   import FactoredFunctions2(SupR,SupS)
-   import CommuteUnivariatePolynomialCategory(S,SupS, SupSupS)
-   import UnivariatePolynomialCategoryFunctions2(S,SupS,SupS,SupSupS)
-   import UnivariatePolynomialCategoryFunctions2(SupS,SupSupS,S,SupS)
-   import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
-   import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
-   import UnivariatePolynomialCategoryFunctions2(S,SupS,SupR,SupSupR)
-   import UnivariatePolynomialCategoryFunctions2(SupR,SupSupR,S,SupS)
-   hensel: (SupS,VarSet,R,List SupS) ->
-           Union(Record(fctrs:List SupS),"failed")
-   chooseSLPEViableSubstitutions: (List VarSet,List SupS,SupS) ->
-    Record(substnsField:List R,lpolysRField:List SupR,ppRField:SupR)
-     --++ chooseSLPEViableSubstitutions(lv,lp,p) chooses substitutions
-     --++ for the variables in first arg (which are all
-     --++ the variables that exist) so that the polys in second argument don't
-     --++ drop in degree and remain square-free, and third arg doesn't drop
-     --++ drop in degree
-   chooseFSQViableSubstitutions: (List VarSet,SupS) ->
-    Record(substnsField:List R,ppRField:SupR)
-     --++ chooseFSQViableSubstitutions(lv,p) chooses substitutions for the variables in first arg (which are all
-     --++ the variables that exist) so that the second argument poly doesn't
-     --++ drop in degree and remains square-free
-   raise: SupR -> SupS
-   lower: SupS -> SupR
-   SLPEBR: (List SupS, List VarSet, SupS, List VarSet)  ->
-                                         Union(List SupS,"failed")
-   factorSFBRlcUnitInner: (List VarSet, SupS,R) ->
-                                         Union(Factored SupS,"failed")
-   hensel(pp,vv,r,factors) ==
-      origFactors:=factors
-      totdegree:Integer:=0
-      proddegree:Integer:=
-                   "max"/[degree(u,vv) for u in coefficients pp]
-      n:PI:=1
-      prime:=vv::S - r::S
-      foundFactors:List SupS:=empty()
-      while (totdegree <= proddegree) repeat
-          pn:=prime**n
-          Ecart:=(pp-*/factors) exquo  pn
-          Ecart case "failed" =>
-                error "failed lifting in hensel in PFBR"
-          zero? Ecart =>
-             -- then we have all the factors
-             return [append(foundFactors, factors)]
-          step:=solveLinearPolynomialEquation(origFactors,
-                                              map(eval(#1,vv,r),
-                                                  Ecart))
-          step case "failed" => return "failed" -- must be a false split
-          factors:=[a+b*pn for a in factors for b in step]
-          for a in factors for c in origFactors repeat
-              pp1:= pp exquo a
-              pp1 case "failed" => "next"
-              pp:=pp1
-              proddegree := proddegree - "max"/[degree(u,vv)
-                                                for u in coefficients a]
-              factors:=remove(a,factors)
-              origFactors:=remove(c,origFactors)
-              foundFactors:=[a,:foundFactors]
-          #factors < 2 =>
-             return [(empty? factors => foundFactors;
-                                     [pp,:foundFactors])]
-          totdegree:= +/["max"/[degree(u,vv)
-                                for u in coefficients u1]
-                         for u1 in factors]
-          n:=n+1
-      "failed" -- must have been a false split
-
-   factorSFBRlcUnitInner(lvpp,pp,r) ==
-      -- pp is square-free as a Sup, and its coefficients have precisely
-      -- the variables of lvpp. Furthermore, its LC is a unit
-      -- returns "failed" if the substitution is bad, else a factorization
-      ppR:=map(eval(#1,first lvpp,r),pp)
-      degree ppR < degree pp => "failed"
-      degree gcd(ppR,differentiate ppR) >0 => "failed"
-      factors:=
-         empty? rest lvpp =>
-            fDown:=factorSquareFreePolynomial map(retract(#1)::R,ppR)
-            [raise (unit fDown * factorList(fDown).first.fctr),
-             :[raise u.fctr for u in factorList(fDown).rest]]
-         fSame:=factorSFBRlcUnit(rest lvpp,ppR)
-         [unit fSame * factorList(fSame).first.fctr,
-          :[uu.fctr for uu in factorList(fSame).rest]]
-      #factors = 1 => makeFR(1,[["irred",pp,1]])
-      hen:=hensel(pp,first lvpp,r,factors)
-      hen case "failed" => "failed"
-      makeFR(1,[["irred",u,1] for u in hen.fctrs])
-   if R has StepThrough then
-     factorSFBRlcUnit(lvpp,pp) ==
-       val:R := init()
-       while true repeat
-          tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
-          not (tempAns case "failed") => return tempAns
-          val1:=nextItem val
-          val1 case "failed" =>
-            error "at this point, we know we have a finite field"
-          val:=val1
-   else
-     factorSFBRlcUnit(lvpp,pp) ==
-       val:R := randomR()
-       while true repeat
-          tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
-          not (tempAns case "failed") => return tempAns
-          val := randomR()
-   if R has random: -> R then
-      randomR() == random()
-   else randomR() == (random()$Integer)::R
-   if R has FiniteFieldCategory then
-     bivariateSLPEBR(lpolys,pp,v) ==
-       lpolysR:List SupSupR:=[map(univariate,u) for u in lpolys]
-       ppR: SupSupR:=map(univariate,pp)
-       ans:=solveLinearPolynomialEquation(lpolysR,ppR)$SupR
-       ans case "failed" => "failed"
-       [map(multivariate(#1,v),w) for w in ans]
-   else
-     bivariateSLPEBR(lpolys,pp,v) ==
-       solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
-   chooseFSQViableSubstitutions(lvpp,pp) ==
-     substns:List R
-     ppR: SupR
-     while true repeat
-        substns:= [randomR() for v in lvpp]
-        zero? eval(leadingCoefficient pp,lvpp,substns ) => "next"
-        ppR:=map((retract eval(#1,lvpp,substns))::R,pp)
-        degree gcd(ppR,differentiate ppR)>0 => "next"
-        leave
-     [substns,ppR]
-   chooseSLPEViableSubstitutions(lvpolys,lpolys,pp) ==
-     substns:List R
-     lpolysR:List SupR
-     ppR: SupR
-     while true repeat
-        substns:= [randomR() for v in lvpolys]
-        zero? eval(leadingCoefficient pp,lvpolys,substns ) => "next"
-        "or"/[zero? eval(leadingCoefficient u,lvpolys,substns)
-                    for u in lpolys] => "next"
-        lpolysR:=[map((retract eval(#1,lvpolys,substns))::R,u)
-                  for u in lpolys]
-        uu:=lpolysR
-        while not empty? uu repeat
-          "or"/[ degree(gcd(uu.first,v))>0 for v in uu.rest] => leave
-          uu:=rest uu
-        not empty? uu => "next"
-        leave
-     ppR:=map((retract eval(#1,lvpolys,substns))::R,pp)
-     [substns,lpolysR,ppR]
-   raise(supR) == map(#1:R::S,supR)
-   lower(pp) == map(retract(#1)::R,pp)
-   SLPEBR(lpolys,lvpolys,pp,lvpp) ==
-     not empty? (m:=setDifference(lvpp,lvpolys)) =>
-         v:=first m
-         lvpp:=remove(v,lvpp)
-         pp1:SupSupS :=swap map(univariate(#1,v),pp)
-         -- pp1 is mathematically equal to pp, but is in S[z][v]
-         -- so we wish to operate on all of its coefficients
-         ans:List SupSupS:= [0 for u in lpolys]
-         for m in reverse_! monomials pp1 repeat
-             ans1:=SLPEBR(lpolys,lvpolys,leadingCoefficient m,lvpp)
-             ans1 case "failed" => return "failed"
-             d:=degree m
-             ans:=[monomial(a1,d)+a for a in ans for a1 in ans1]
-         [map(multivariate(#1,v),swap pp1) for pp1 in ans]
-     empty? lvpolys =>
-         lpolysR:List SupR
-         ppR:SupR
-         lpolysR:=[map(retract,u) for u in lpolys]
-         ppR:=map(retract,pp)
-         ansR:=solveLinearPolynomialEquation(lpolysR,ppR)
-         ansR case "failed" => return "failed"
-         [map(#1::S,uu) for uu in ansR]
-     cVS:=chooseSLPEViableSubstitutions(lvpolys,lpolys,pp)
-     ansR:=solveLinearPolynomialEquation(cVS.lpolysRField,cVS.ppRField)
-     ansR case "failed" => "failed"
-     #lvpolys = 1 => bivariateSLPEBR(lpolys,pp, first lvpolys)
-     solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
-
-   solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
-     lvpolys := removeDuplicates_!
-                  concat [ concat [variables z for z in coefficients u]
-                                               for u in lpolys]
-     lvpp := removeDuplicates_!
-                concat [variables z for z in coefficients pp]
-     SLPEBR(lpolys,lvpolys,pp,lvpp)
-
-   factorByRecursion pp ==
-     lv:List(VarSet) := removeDuplicates_!
-                           concat [variables z for z in coefficients pp]
-     empty? lv =>
-         map(raise,factorPolynomial lower pp)
-     c:=content pp
-     unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
-     pp:=(pp exquo c)::SupS
-     mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
-                  map(#1:S::SupS,factor(c)$S))
-   factorSquareFreeByRecursion pp ==
-     lv:List(VarSet) := removeDuplicates_!
-                           concat [variables z for z in coefficients pp]
-     empty? lv =>
-         map(raise,factorPolynomial lower pp)
-     unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(lv,pp)
-     oldnfact:NonNegativeInteger:= 999999
-                       -- I hope we never have to factor a polynomial
-                       -- with more than this number of factors
-     lcppPow:S
-     while true repeat
-       cVS:=chooseFSQViableSubstitutions(lv,pp)
-       factorsR:=factorSquareFreePolynomial(cVS.ppRField)
-       (nfact:=numberOfFactors factorsR) = 1 =>
-                  return makeFR(1,[["irred",pp,1]])
-       -- OK, force all leading coefficients to be equal to the leading
-       -- coefficient of the input
-       nfact > oldnfact => "next"   -- can't be a good reduction
-       oldnfact:=nfact
-       factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
-                  for u in factorList factorsR]
-       ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
-       lvppList:=lv
-       OK:=true
-       for u in lvppList for v in cVS.substnsField repeat
-           hen:=hensel(ppAdjust,u,v,factors)
-           hen case "failed" =>
-               OK:=false
-               "leave"
-           factors:=hen.fctrs
-       OK => leave
-     factors:=[ (lc:=content w;
-                 lcppPow:=(lcppPow exquo lc)::S;
-                  (w exquo lc)::SupS)
-                for w in factors]
-     not unit? lcppPow =>
-         error "internal error in factorSquareFreeByRecursion"
-     makeFR((recip lcppPow)::S::SupS,
-             [["irred",w,1] for w in factors])
-
-@
-\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 PFBRU PolynomialFactorizationByRecursionUnivariate>>
-<<package PFBR PolynomialFactorizationByRecursion>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pfo.spad.pamphlet b/src/algebra/pfo.spad.pamphlet
deleted file mode 100644
index 1b310c4..0000000
--- a/src/algebra/pfo.spad.pamphlet
+++ /dev/null
@@ -1,612 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pfo.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package FORDER FindOrderFinite}
-<<package FORDER FindOrderFinite>>=
-)abbrev package FORDER FindOrderFinite
-++ Finds the order of a divisor over a finite field
-++ Author: Manuel Bronstein
-++ Date Created: 1988
-++ Date Last Updated: 11 Jul 1990
-FindOrderFinite(F, UP, UPUP, R): Exports == Implementation where
-  F   : Join(Finite, Field)
-  UP  : UnivariatePolynomialCategory F
-  UPUP: UnivariatePolynomialCategory Fraction UP
-  R   : FunctionFieldCategory(F, UP, UPUP)
-
-  Exports ==> with
-    order: FiniteDivisor(F, UP, UPUP, R) -> NonNegativeInteger
-	++ order(x) \undocumented
-  Implementation ==> add
-    order d ==
-      dd := d := reduce d
-      for i in 1.. repeat
-        principal? dd => return(i::NonNegativeInteger)
-        dd := reduce(d + dd)
-
-@
-\section{package RDIV ReducedDivisor}
-<<package RDIV ReducedDivisor>>=
-)abbrev package RDIV ReducedDivisor
-++ Finds the order of a divisor over a finite field
-++ Author: Manuel Bronstein
-++ Date Created: 1988
-++ Date Last Updated: 8 November 1994
-ReducedDivisor(F1, UP, UPUP, R, F2): Exports == Implementation where
-  F1    : Field
-  UP    : UnivariatePolynomialCategory F1
-  UPUP  : UnivariatePolynomialCategory Fraction UP
-  R     : FunctionFieldCategory(F1, UP, UPUP)
-  F2    : Join(Finite, Field)
-
-  N     ==> NonNegativeInteger
-  FD    ==> FiniteDivisor(F1, UP, UPUP, R)
-  UP2   ==> SparseUnivariatePolynomial F2
-  UPUP2 ==> SparseUnivariatePolynomial Fraction UP2
-
-  Exports ==> with
-    order: (FD, UPUP, F1 -> F2) -> N
-	++ order(f,u,g) \undocumented
-
-  Implementation ==> add
-    algOrder : (FD, UPUP, F1 -> F2)  -> N
-    rootOrder: (FD, UP, N, F1 -> F2) -> N
-
--- pp is not necessarily monic
-    order(d, pp, f) ==
-      (r := retractIfCan(reductum pp)@Union(Fraction UP, "failed"))
-        case "failed" => algOrder(d, pp, f)
-      rootOrder(d, - retract(r::Fraction(UP) / leadingCoefficient pp)@UP,
-                degree pp, f)
-
-    algOrder(d, modulus, reduce) ==
-      redmod := map(reduce, modulus)$MultipleMap(F1,UP,UPUP,F2,UP2,UPUP2)
-      curve  := AlgebraicFunctionField(F2, UP2, UPUP2, redmod)
-      order(map(reduce,
-              d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
-                                 )$FindOrderFinite(F2, UP2, UPUP2, curve)
-
-    rootOrder(d, radicand, n, reduce) ==
-      redrad := map(reduce,
-           radicand)$UnivariatePolynomialCategoryFunctions2(F1,UP,F2,UP2)
-      curve  := RadicalFunctionField(F2, UP2, UPUP2, redrad::Fraction UP2, n)
-      order(map(reduce,
-              d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
-                                 )$FindOrderFinite(F2, UP2, UPUP2, curve)
-
-@
-\section{package PFOTOOLS PointsOfFiniteOrderTools}
-<<package PFOTOOLS PointsOfFiniteOrderTools>>=
-)abbrev package PFOTOOLS PointsOfFiniteOrderTools
-++ Utilities for PFOQ and PFO
-++ Author: Manuel Bronstein
-++ Date Created: 25 Aug 1988
-++ Date Last Updated: 11 Jul 1990
-PointsOfFiniteOrderTools(UP, UPUP): Exports == Implementation where
-  UP   : UnivariatePolynomialCategory Fraction Integer
-  UPUP : UnivariatePolynomialCategory Fraction UP
-
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  Q   ==> Fraction Integer
-
-  Exports ==> with
-    getGoodPrime : Z -> PI
-      ++ getGoodPrime n returns the smallest prime not dividing n
-    badNum       : UP   -> Record(den:Z, gcdnum:Z)
-	++ badNum(p) \undocumented
-    badNum       : UPUP -> Z
-	++ badNum(u) \undocumented
-    mix          : List Record(den:Z, gcdnum:Z) -> Z
-	++ mix(l) \undocumented
-    doubleDisc   : UPUP -> Z
-	++ doubleDisc(u) \undocumented
-    polyred      : UPUP -> UPUP
-	++ polyred(u) \undocumented
-
-  Implementation ==> add
-    import IntegerPrimesPackage(Z)
-    import UnivariatePolynomialCommonDenominator(Z, Q, UP)
-
-    mix l          == lcm(lcm [p.den for p in l], gcd [p.gcdnum for p in l])
-    badNum(p:UPUP) == mix [badNum(retract(c)@UP) for c in coefficients p]
-
-    polyred r ==
-      lcm [commonDenominator(retract(c)@UP) for c in coefficients r] * r
-
-    badNum(p:UP) ==
-      cd := splitDenominator p
-      [cd.den, gcd [retract(c)@Z for c in coefficients(cd.num)]]
-
-    getGoodPrime n ==
-      p:PI := 3
-      while zero?(n rem p) repeat
-        p := nextPrime(p::Z)::PI
-      p
-
-    doubleDisc r ==
-      d := retract(discriminant r)@UP
-      retract(discriminant((d exquo gcd(d, differentiate d))::UP))@Z
-
-@
-\section{package PFOQ PointsOfFiniteOrderRational}
-<<package PFOQ PointsOfFiniteOrderRational>>=
-)abbrev package PFOQ PointsOfFiniteOrderRational
-++ Finds the order of a divisor on a rational curve
-++ Author: Manuel Bronstein
-++ Date Created: 25 Aug 1988
-++ Date Last Updated: 3 August 1993
-++ Description:
-++ This package provides function for testing whether a divisor on a
-++ curve is a torsion divisor.
-++ Keywords: divisor, algebraic, curve.
-++ Examples: )r PFOQ INPUT
-PointsOfFiniteOrderRational(UP, UPUP, R): Exports == Implementation where
-  UP   : UnivariatePolynomialCategory Fraction Integer
-  UPUP : UnivariatePolynomialCategory Fraction UP
-  R    : FunctionFieldCategory(Fraction Integer, UP, UPUP)
-
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  Q   ==> Fraction Integer
-  FD  ==> FiniteDivisor(Q, UP, UPUP, R)
-
-  Exports ==> with
-    order       : FD -> Union(N, "failed")
-	++ order(f) \undocumented
-    torsion?    : FD -> Boolean
-	++ torsion?(f) \undocumented
-    torsionIfCan: FD -> Union(Record(order:N, function:R), "failed")
-	++ torsionIfCan(f) \undocumented
-
-  Implementation ==> add
-    import PointsOfFiniteOrderTools(UP, UPUP)
-
-    possibleOrder: FD -> N
-    ratcurve     : (FD, UPUP, Z) -> N
-    rat          : (UPUP, FD, PI) -> N
-
-    torsion? d  == order(d) case N
-
--- returns the potential order of d, 0 if d is of infinite order
-    ratcurve(d, modulus, disc) ==
-      mn  := minIndex(nm := numer(i := ideal d))
-      h   := lift(hh := nm(mn + 1))
-      s   := separate(retract(norm hh)@UP,
-               b := retract(retract(nm.mn)@Fraction(UP))@UP).primePart
-      bd  := badNum denom i
-      r   := resultant(s, b)
-      bad := lcm [disc, numer r, denom r, bd.den * bd.gcdnum, badNum h]$List(Z)
-      n   := rat(modulus, d, p := getGoodPrime bad)
--- if n > 1 then it is cheaper to compute the order modulo a second prime,
--- since computing n * d could be very expensive
---      one? n => n
-      (n = 1) => n
-      m   := rat(modulus, d, getGoodPrime(p * bad))
-      n = m => n
-      0
-
-    rat(pp, d, p) ==
-      gf := InnerPrimeField p
-      order(d, pp,
-        numer(#1)::gf / denom(#1)::gf)$ReducedDivisor(Q, UP, UPUP, R, gf)
-
--- returns the potential order of d, 0 if d is of infinite order
-    possibleOrder d ==
---      zero?(genus()) or one?(#(numer ideal d)) => 1
-      zero?(genus()) or (#(numer ideal d) = 1) => 1
-      r := polyred definingPolynomial()$R
-      ratcurve(d, r, doubleDisc r)
-
-    order d ==
-      zero?(n := possibleOrder(d := reduce d)) => "failed"
-      principal? reduce(n::Z * d) => n
-      "failed"
-
-    torsionIfCan d ==
-      zero?(n := possibleOrder(d := reduce d)) => "failed"
-      (g := generator reduce(n::Z * d)) case "failed" => "failed"
-      [n, g::R]
-
-@
-\section{package FSRED FunctionSpaceReduce}
-<<package FSRED FunctionSpaceReduce>>=
-)abbrev package FSRED FunctionSpaceReduce
-++ Reduction from a function space to the rational numbers
-++ Author: Manuel Bronstein
-++ Date Created: 1988
-++ Date Last Updated: 11 Jul 1990
-++ Description:
-++ This package provides function which replaces transcendental kernels
-++ in a function space by random integers. The correspondence between
-++ the kernels and the integers is fixed between calls to new().
-++ Keywords: function, space, redcution.
-FunctionSpaceReduce(R, F): Exports == Implementation where
-  R: Join(OrderedSet, IntegralDomain, RetractableTo Integer)
-  F: FunctionSpace R
-
-  Z   ==> Integer
-  Q   ==> Fraction Integer
-  UP  ==> SparseUnivariatePolynomial Q
-  K   ==> Kernel F
-  ALGOP  ==> "%alg"
-
-  Exports ==> with
-    bringDown: F -> Q
-	++ bringDown(f) \undocumented
-    bringDown: (F, K) -> UP
-	++ bringDown(f,k) \undocumented
-    newReduc : () -> Void
-	++ newReduc() \undocumented
-
-  Implementation ==> add
-    import SparseUnivariatePolynomialFunctions2(F, Q)
-    import PolynomialCategoryQuotientFunctions(IndexedExponents K,
-                         K, R, SparseMultivariatePolynomial(R, K), F)
-
-    K2Z : K -> F
-
-    redmap := table()$AssociationList(K, Z)
-
-    newReduc() ==
-      for k in keys redmap repeat remove_!(k, redmap)
-      void
-
-    bringDown(f, k) ==
-      ff := univariate(f, k)
-      (bc := extendedEuclidean(map(bringDown, denom ff),
-                m := map(bringDown, minPoly k), 1)) case "failed" =>
-                     error "denominator is 0"
-      (map(bringDown, numer ff) * bc.coef1) rem m
-
-    bringDown f ==
-      retract(eval(f, lk := kernels f, [K2Z k for k in lk]))@Q
-
-    K2Z k ==
-      has?(operator k, ALGOP) => error "Cannot reduce constant field"
-      (u := search(k, redmap)) case "failed" =>
-                                      setelt(redmap, k, random()$Z)::F
-      u::Z::F
-
-@
-\section{package PFO PointsOfFiniteOrder}
-<<package PFO PointsOfFiniteOrder>>=
-)abbrev package PFO PointsOfFiniteOrder
-++ Finds the order of a divisor on a curve
-++ Author: Manuel Bronstein
-++ Date Created: 1988
-++ Date Last Updated: 22 July 1998
-++ Description:
-++ This package provides function for testing whether a divisor on a
-++ curve is a torsion divisor.
-++ Keywords: divisor, algebraic, curve.
-++ Examples: )r PFO INPUT
-PointsOfFiniteOrder(R0, F, UP, UPUP, R): Exports == Implementation where
-  R0   : Join(OrderedSet, IntegralDomain, RetractableTo Integer)
-  F    : FunctionSpace R0
-  UP   : UnivariatePolynomialCategory F
-  UPUP : UnivariatePolynomialCategory Fraction UP
-  R    : FunctionFieldCategory(F, UP, UPUP)
-
-  PI  ==> PositiveInteger
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  Q   ==> Fraction Integer
-  UPF ==> SparseUnivariatePolynomial F
-  UPQ ==> SparseUnivariatePolynomial Q
-  QF  ==> Fraction UP
-  UPUPQ ==> SparseUnivariatePolynomial Fraction UPQ
-  UP2 ==> SparseUnivariatePolynomial UPQ
-  UP3 ==> SparseUnivariatePolynomial UP2
-  FD  ==> FiniteDivisor(F, UP, UPUP, R)
-  K   ==> Kernel F
-  REC ==> Record(ncurve:UP3, disc:Z, dfpoly:UPQ)
-  RC0 ==> Record(ncurve:UPUPQ, disc:Z)
-  ID  ==> FractionalIdeal(UP, QF, UPUP, R)
-  SMP ==> SparseMultivariatePolynomial(R0,K)
-  ALGOP  ==> "%alg"
-
-  Exports ==> with
-    order        : FD -> Union(N, "failed")
-	++ order(f) \undocumented
-    torsion?     : FD -> Boolean
-	++ torsion?(f) \undocumented
-    torsionIfCan : FD -> Union(Record(order:N, function:R), "failed")
-	++ torsionIfCan(f)\ undocumented
-
-  Implementation ==> add
-    import IntegerPrimesPackage(Z)
-    import PointsOfFiniteOrderTools(UPQ, UPUPQ)
-    import UnivariatePolynomialCommonDenominator(Z, Q, UPQ)
-
-    cmult: List SMP -> SMP
-    raise         : (UPQ, K) -> F
-    raise2        : (UP2, K) -> UP
-    qmod          : F     -> Q
-    fmod          : UPF   -> UPQ
-    rmod          : UP    -> UPQ
-    pmod          : UPUP  -> UPUPQ
-    kqmod         : (F,    K) -> UPQ
-    krmod         : (UP,   K) -> UP2
-    kpmod         : (UPUP, K) -> UP3
-    selectIntegers: K   -> REC
-    selIntegers:    ()  -> RC0
-    possibleOrder : FD -> N
-    ratcurve      : (FD, RC0)    -> N
-    algcurve      : (FD, REC, K) -> N
-    kbad3Num      : (UP3, UPQ) -> Z
-    kbadBadNum    : (UP2, UPQ) -> Z
-    kgetGoodPrime : (REC, UPQ, UP3, UP2,UP2) -> Record(prime:PI,poly:UPQ)
-    goodRed       : (REC, UPQ, UP3, UP2, UP2, PI) -> Union(UPQ, "failed")
-    good?         : (UPQ, UP3, UP2, UP2, PI, UPQ) -> Boolean
-    klist         : UP -> List K
-    aklist        : R  -> List K
-    alglist       : FD -> List K
-    notIrr?       : UPQ -> Boolean
-    rat           : (UPUP, FD, PI) -> N
-    toQ1          : (UP2, UPQ) -> UP
-    toQ2          : (UP3, UPQ) -> R
-    Q2F           : Q -> F
-    Q2UPUP        : UPUPQ -> UPUP
-
-    q := FunctionSpaceReduce(R0, F)
-
-    torsion? d == order(d) case N
-    Q2F x      == numer(x)::F / denom(x)::F
-    qmod x     == bringDown(x)$q
-    kqmod(x,k) == bringDown(x, k)$q
-    fmod p     == map(qmod, p)$SparseUnivariatePolynomialFunctions2(F, Q)
-    pmod p     == map(qmod, p)$MultipleMap(F, UP, UPUP, Q, UPQ, UPUPQ)
-    Q2UPUP p   == map(Q2F, p)$MultipleMap(Q, UPQ, UPUPQ, F, UP, UPUP)
-    klist d    == "setUnion"/[kernels c for c in coefficients d]
-    notIrr? d  == #(factors factor(d)$RationalFactorize(UPQ)) > 1
-    kbadBadNum(d, m) == mix [badNum(c rem m) for c in coefficients d]
-    kbad3Num(h, m)   == lcm [kbadBadNum(c, m) for c in coefficients h]
-    
-    torsionIfCan d ==
-      zero?(n := possibleOrder(d := reduce d)) => "failed"
-      (g := generator reduce(n::Z * d)) case "failed" => "failed"
-      [n, g::R]
-
-    UPQ2F(p:UPQ, k:K):F ==
-      map(Q2F, p)$UnivariatePolynomialCategoryFunctions2(Q, UPQ, F, UP) (k::F)
-
-    UP22UP(p:UP2, k:K):UP ==
-      map(UPQ2F(#1, k), p)$UnivariatePolynomialCategoryFunctions2(UPQ,UP2,F,UP)
-
-    UP32UPUP(p:UP3, k:K):UPUP ==
-      map(UP22UP(#1,k)::QF,
-          p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
-
-    if R0 has GcdDomain then
-       cmult(l:List SMP):SMP == lcm l
-    else
-       cmult(l:List SMP):SMP == */l
-
-    doubleDisc(f:UP3):Z ==
-      d := discriminant f
-      g := gcd(d, differentiate d)
-      d := (d exquo g)::UP2
-      zero?(e := discriminant d) => 0
-      gcd [retract(c)@Z for c in coefficients e]
-
-    commonDen(p:UP):SMP ==
-      l1:List F := coefficients p
-      l2:List SMP := [denom c for c in l1]
-      cmult l2
-
-    polyred(f:UPUP):UPUP ==
-      cmult([commonDen(retract(c)@UP) for c in coefficients f])::F::UP::QF * f
-
-    aklist f ==
-      (r := retractIfCan(f)@Union(QF, "failed")) case "failed" =>
-        "setUnion"/[klist(retract(c)@UP) for c in coefficients lift f]
-      klist(retract(r::QF)@UP)
-
-    alglist d ==
-      n := numer(i := ideal d)
-      select_!(has?(operator #1, ALGOP),
-               setUnion(klist denom i,
-                 "setUnion"/[aklist qelt(n,i) for i in minIndex n..maxIndex n]))
-
-    krmod(p,k) ==
-       map(kqmod(#1, k),
-           p)$UnivariatePolynomialCategoryFunctions2(F, UP, UPQ, UP2)
-
-    rmod p ==
-       map(qmod, p)$UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
-
-    raise(p, k) ==
-      (map(Q2F, p)$SparseUnivariatePolynomialFunctions2(Q, F)) (k::F)
-
-    raise2(p, k) ==
-      map(raise(#1, k),
-          p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
-
-    algcurve(d, rc, k) ==
-      mn := minIndex(n := numer(i := minimize ideal d))
-      h  := kpmod(lift(hh := n(mn + 1)), k)
-      b2 := primitivePart
-                 raise2(b := krmod(retract(retract(n.mn)@QF)@UP, k), k)
-      s  := kqmod(resultant(primitivePart separate(raise2(krmod(
-                    retract(norm hh)@UP, k), k), b2).primePart, b2), k)
-      pr := kgetGoodPrime(rc, s, h, b, dd := krmod(denom i, k))
-      p  := pr.prime
-      pp := UP32UPUP(rc.ncurve, k)
-      mm := pr.poly
-      gf := InnerPrimeField p
-      m  := map(retract(#1)@Z :: gf,
-                         mm)$SparseUnivariatePolynomialFunctions2(Q, gf)
---      one? degree m =>
-      (degree m = 1) =>
-        alpha := - coefficient(m, 0) / leadingCoefficient m
-        order(d, pp,
-           (map(numer(#1)::gf / denom(#1)::gf,
-            kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))(alpha)
-                                   )$ReducedDivisor(F, UP, UPUP, R, gf)
-        -- d1 := toQ1(dd, mm)
-        -- rat(pp, divisor ideal([(toQ1(b, mm) / d1)::QF::R,
-                                       -- inv(d1::QF) * toQ2(h,mm)])$ID, p)
-      sae:= SimpleAlgebraicExtension(gf,SparseUnivariatePolynomial gf,m)
-      order(d, pp,
-           reduce(map(numer(#1)::gf / denom(#1)::gf,
-            kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))$sae
-                                   )$ReducedDivisor(F, UP, UPUP, R, sae)
-
--- returns the potential order of d, 0 if d is of infinite order
-    ratcurve(d, rc) ==
-      mn  := minIndex(nm := numer(i := minimize ideal d))
-      h   := pmod lift(hh := nm(mn + 1))
-      b   := rmod(retract(retract(nm.mn)@QF)@UP)
-      s   := separate(rmod(retract(norm hh)@UP), b).primePart
-      bd  := badNum rmod denom i
-      r   := resultant(s, b)
-      bad := lcm [rc.disc, numer r, denom r, bd.den*bd.gcdnum, badNum h]$List(Z)
-      pp  := Q2UPUP(rc.ncurve)
-      n   := rat(pp, d, p := getGoodPrime bad)
--- if n > 1 then it is cheaper to compute the order modulo a second prime,
--- since computing n * d could be very expensive
---      one? n => n
-      (n = 1) => n
-      m   := rat(pp, d, getGoodPrime(p * bad))
-      n = m => n
-      0
-
--- returns the order of d mod p
-    rat(pp, d, p) ==
-      gf := InnerPrimeField p
-      order(d, pp, (qq := qmod #1;numer(qq)::gf / denom(qq)::gf)
-                                    )$ReducedDivisor(F, UP, UPUP, R, gf)
-
--- returns the potential order of d, 0 if d is of infinite order
-    possibleOrder d ==
---      zero?(genus()) or one?(#(numer ideal d)) => 1
-      zero?(genus()) or (#(numer ideal d) = 1) => 1
-      empty?(la := alglist d) => ratcurve(d, selIntegers())
-      not(empty? rest la) =>
-           error "PFO::possibleOrder: more than 1 algebraic constant"
-      algcurve(d, selectIntegers first la, first la)
-
-    selIntegers():RC0 ==
-      f := definingPolynomial()$R
-      while zero?(d := doubleDisc(r := polyred pmod f)) repeat newReduc()$q
-      [r, d]
-
-    selectIntegers(k:K):REC ==
-      g := polyred(f := definingPolynomial()$R)
-      p := minPoly k
-      while zero?(d := doubleDisc(r := kpmod(g, k))) or (notIrr? fmod p)
-          repeat newReduc()$q
-      [r, d, splitDenominator(fmod p).num]
-
-    toQ1(p, d) ==
-      map(Q2F(retract(#1 rem d)@Q),
-          p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
-
-    toQ2(p, d) ==
-      reduce map(toQ1(#1, d)::QF,
-        p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
-
-    kpmod(p, k) ==
-      map(krmod(retract(#1)@UP, k),
-        p)$UnivariatePolynomialCategoryFunctions2(QF, UPUP, UP2, UP3)
-
-    order d ==
-      zero?(n := possibleOrder(d := reduce d)) => "failed"
-      principal? reduce(n::Z * d) => n
-      "failed"
-
-    kgetGoodPrime(rec, res, h, b, d) ==
-      p:PI := 3
-      while (u := goodRed(rec, res, h, b, d, p)) case "failed" repeat
-        p := nextPrime(p::Z)::PI
-      [p, u::UPQ]
-
-    goodRed(rec, res, h, b, d, p) ==
-      zero?(rec.disc rem p) => "failed"
-      gf := InnerPrimeField p
-      l  := [f.factor for f in factors factor(map(retract(#1)@Z :: gf,
-               rec.dfpoly)$SparseUnivariatePolynomialFunctions2(Q,
-                 gf))$DistinctDegreeFactorize(gf,
---                   SparseUnivariatePolynomial gf) | one?(f.exponent)]
-                   SparseUnivariatePolynomial gf) | (f.exponent = 1)]
-      empty? l => "failed"
-      mdg := first l
-      for ff in rest l repeat
-        if degree(ff) < degree(mdg) then mdg := ff
-      md := map(convert(#1)@Z :: Q,
-                 mdg)$SparseUnivariatePolynomialFunctions2(gf, Q)
-      good?(res, h, b, d, p, md) => md
-      "failed"
-
-    good?(res, h, b, d, p, m) ==
-      bd := badNum(res rem m)
-      not (zero?(bd.den rem p) or zero?(bd.gcdnum rem p) or
-        zero?(kbadBadNum(b,m) rem p) or zero?(kbadBadNum(d,m) rem p)
-              or zero?(kbad3Num(h, m) rem 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>>
-
--- SPAD files for the integration world should be compiled in the
--- following order:
---
---   intaux  rderf  intrf  curve  curvepkg  divisor  PFO
---   intalg  intaf  efstruc  rdeef  intef  irexpand  integrat
-
-<<package FORDER FindOrderFinite>>
-<<package RDIV ReducedDivisor>>
-<<package PFOTOOLS PointsOfFiniteOrderTools>>
-<<package PFOQ PointsOfFiniteOrderRational>>
-<<package FSRED FunctionSpaceReduce>>
-<<package PFO PointsOfFiniteOrder>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pfr.spad.pamphlet b/src/algebra/pfr.spad.pamphlet
deleted file mode 100644
index 9598392..0000000
--- a/src/algebra/pfr.spad.pamphlet
+++ /dev/null
@@ -1,108 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pfr.spad}
-\author{Robert Sutor, Barry Trager}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PFRPAC PartialFractionPackage}
-<<package PFRPAC PartialFractionPackage>>=
-)abbrev package PFRPAC PartialFractionPackage
-++ Author: Barry M. Trager
-++ Date Created: 1992
-++ BasicOperations:
-++ Related Constructors: PartialFraction
-++ Also See:
-++ AMS Classifications:
-++ Keywords: partial fraction, factorization, euclidean domain
-++ References:
-++ Description:
-++   The package \spadtype{PartialFractionPackage} gives an easier
-++   to use interfact the domain \spadtype{PartialFraction}.
-++   The user gives a fraction of polynomials, and a variable and
-++   the package converts it to the proper datatype for the
-++   \spadtype{PartialFraction} domain.
-
-PartialFractionPackage(R): Cat == Capsule where
---  R : UniqueFactorizationDomain -- not yet supported
-   R : Join(EuclideanDomain, CharacteristicZero)
-   FPR ==> Fraction Polynomial R
-   INDE ==> IndexedExponents Symbol
-   PR ==> Polynomial R
-   SUP ==> SparseUnivariatePolynomial
-   Cat == with
-      partialFraction: (FPR, Symbol) -> Any
-         ++ partialFraction(rf, var) returns the partial fraction decomposition
-         ++ of the rational function rf with respect to the variable var.
-      partialFraction: (PR, Factored PR, Symbol) -> Any
-         ++ partialFraction(num, facdenom, var) returns the partial fraction
-         ++ decomposition of the rational function whose numerator is num and
-         ++ whose factored denominator is facdenom with respect to the variable var.
-   Capsule == add
-      partialFraction(rf, v) ==
-         df := factor(denom rf)$MultivariateFactorize(Symbol, INDE,R,PR)
-         partialFraction(numer rf, df, v)
-
-      makeSup(p:Polynomial R, v:Symbol) : SparseUnivariatePolynomial FPR ==
-         up := univariate(p,v)
-         map(#1::FPR,up)$UnivariatePolynomialCategoryFunctions2(PR, SUP PR, FPR, SUP FPR)
-
-      partialFraction(p, facq, v) ==
-         up := UnivariatePolynomial(v, Fraction Polynomial R)
-         fup := Factored up
-         ffact : List(Record(irr:up,pow:Integer))
-         ffact:=[[makeSup(u.factor,v) pretend up,u.exponent]
-                      for u in factors facq]
-         fcont:=makeSup(unit facq,v) pretend up
-         nflist:fup := fcont*(*/[primeFactor(ff.irr,ff.pow) for ff in ffact])
-         pfup:=partialFraction(makeSup(p,v) pretend up, nflist)$PartialFraction(up)
-         coerce(pfup)$AnyFunctions1(PartialFraction up)
-
-@
-\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 PFRPAC PartialFractionPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pgcd.spad.pamphlet b/src/algebra/pgcd.spad.pamphlet
deleted file mode 100644
index 8cee7ec..0000000
--- a/src/algebra/pgcd.spad.pamphlet
+++ /dev/null
@@ -1,458 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pgcd.spad}
-\author{Michael Lucks, Patrizia Gianni, Barry Trager, Frederic Lehobey}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PGCD PolynomialGcdPackage}
-\subsection{failure case in gcdPrimitive(p1:SUPP,p2:SUPP) : SUPP}
-Barry Trager has discovered and fixed a bug in pgcd.spad which occasionally
-(depending on choices of random substitutions) could return the 
-wrong gcd. The fix is simply to comment out one line in 
-$gcdPrimitive$ which was causing the division test to be skipped.
-The line used to read:
-\begin{verbatim}
-        degree result=d1 => result
-\end{verbatim}
-but has now been removed.
-<<bmtfix>>=
-@
-
-<<package PGCD PolynomialGcdPackage>>=
-)abbrev package PGCD PolynomialGcdPackage
-++ Author: Michael Lucks, P. Gianni
-++ Date Created:
-++ Date Last Updated: 17 June 1996
-++ Fix History: Moved unitCanonicals for performance (BMT);
-++              Fixed a problem with gcd(x,0) (Frederic Lehobey)
-++ Basic Functions: gcd, content
-++ Related Constructors: Polynomial
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++   This package computes multivariate polynomial gcd's using
-++ a hensel lifting strategy. The contraint on the coefficient
-++ domain is imposed by the lifting strategy. It is assumed that
-++ the coefficient domain has the property that almost all specializations
-++ preserve the degree of the gcd.
- 
-I        ==> Integer
-NNI      ==> NonNegativeInteger
-PI       ==> PositiveInteger
- 
-PolynomialGcdPackage(E,OV,R,P):C == T where
-    R     :  EuclideanDomain
-    P     :  PolynomialCategory(R,E,OV)
-    OV    :  OrderedSet
-    E     :  OrderedAbelianMonoidSup
- 
-    SUPP      ==> SparseUnivariatePolynomial P
- 
-    C == with
-      gcd               :   (P,P)    -> P
-        ++ gcd(p,q) computes the gcd of the two polynomials p and q.
-      gcd               :   List P   -> P
-        ++ gcd(lp) computes the gcd of the list of polynomials lp.
-      gcd               :   (SUPP,SUPP)    -> SUPP
-        ++ gcd(p,q) computes the gcd of the two polynomials p and q.
-      gcd               :   List SUPP   -> SUPP
-        ++ gcd(lp) computes the gcd of the list of polynomials lp.
-      gcdPrimitive      :   (P,P)    -> P
-        ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
-        ++ p and q.
-      gcdPrimitive      :   (SUPP,SUPP)    -> SUPP
-        ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
-        ++ p and q.
-      gcdPrimitive      :   List P   -> P
-        ++ gcdPrimitive lp computes the gcd of the list of primitive
-        ++ polynomials lp.
-
-    T == add
- 
-      SUP      ==> SparseUnivariatePolynomial R
- 
-      LGcd     ==> Record(locgcd:SUPP,goodint:List List R)
-      UTerm    ==> Record(lpol:List SUP,lint:List List R,mpol:SUPP)
-      pmod:R   :=  (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
- 
-      import MultivariateLifting(E,OV,R,P)
-      import FactoringUtilities(E,OV,R,P)
- 
-                 --------  Local  Functions  --------
- 
-      myran           :    Integer   -> Union(R,"failed")
-      better          :    (P,P)     -> Boolean
-      failtest        :   (SUPP,SUPP,SUPP)    -> Boolean
-      monomContent    :   (SUPP)   -> SUPP
-      gcdMonom        :  (SUPP,SUPP)    -> SUPP
-      gcdTermList     :    (P,P)     -> P
-      good            :  (SUPP,List OV,List List R) -> Record(upol:SUP,inval:List List R)
- 
-      chooseVal       :  (SUPP,SUPP,List OV,List List R) -> Union(UTerm,"failed")
-      localgcd        :  (SUPP,SUPP,List OV,List List R) -> LGcd
-      notCoprime      :  (SUPP,SUPP, List NNI,List OV,List List R)   -> SUPP
-      imposelc        : (List SUP,List OV,List R,List P) -> List SUP
- 
-      lift? :(SUPP,SUPP,UTerm,List NNI,List OV) -> Union(s:SUPP,failed:"failed",notCoprime:"notCoprime")
-      lift  :(SUPP,SUP,SUP,P,List OV,List NNI,List R) -> Union(SUPP,"failed")
- 
-                     ---- Local  functions ----
-    -- test if something wrong happened in the gcd
-      failtest(f:SUPP,p1:SUPP,p2:SUPP) : Boolean ==
-        (p1 exquo f) case "failed" or (p2 exquo f) case "failed"
- 
-    -- Choose the integers
-      chooseVal(p1:SUPP,p2:SUPP,lvr:List OV,ltry:List List R):Union(UTerm,"failed") ==
-        d1:=degree(p1)
-        d2:=degree(p2)
-        dd:NNI:=0$NNI
-        nvr:NNI:=#lvr
-        lval:List R :=[]
-        range:I:=8
-        repeat
-          range:=2*range
-          lval:=[ran(range) for i in 1..nvr]
-          member?(lval,ltry) => "new point"
-          ltry:=cons(lval,ltry)
-          uf1:SUP:=completeEval(p1,lvr,lval)
-          degree uf1 ^= d1 => "new point"
-          uf2:SUP:= completeEval(p2,lvr,lval)
-          degree uf2 ^= d2 => "new point"
-          u:=gcd(uf1,uf2)
-          du:=degree u
-         --the univariate gcd is 1
-          if du=0 then return [[1$SUP],ltry,0$SUPP]$UTerm
- 
-          ugcd:List SUP:=[u,(uf1 exquo u)::SUP,(uf2 exquo u)::SUP]
-          uterm:=[ugcd,ltry,0$SUPP]$UTerm
-          dd=0 => dd:=du
- 
-        --the degree is not changed
-          du=dd =>
- 
-           --test if one of the polynomials is the gcd
-            dd=d1 =>
-              if ^((f:=p2 exquo p1) case "failed") then
-                return [[u],ltry,p1]$UTerm
-              if dd^=d2 then dd:=(dd-1)::NNI
- 
-            dd=d2 =>
-              if ^((f:=p1 exquo p2) case "failed") then
-                return [[u],ltry,p2]$UTerm
-              dd:=(dd-1)::NNI
-            return uterm
- 
-         --the new gcd has degree less
-          du<dd => dd:=du
- 
-      good(f:SUPP,lvr:List OV,ltry:List List R):Record(upol:SUP,inval:List List R) ==
-        nvr:NNI:=#lvr
-        range:I:=1
-        while true repeat
-          range:=2*range
-          lval:=[ran(range) for i in 1..nvr]
-          member?(lval,ltry) => "new point"
-          ltry:=cons(lval,ltry)
-          uf:=completeEval(f,lvr,lval)
-          if degree gcd(uf,differentiate uf)=0 then return [uf,ltry]
- 
-      -- impose the right lc
-      imposelc(lipol:List SUP,
-               lvar:List OV,lval:List R,leadc:List P):List SUP ==
-        result:List SUP :=[]
-        for pol in lipol for leadpol in leadc repeat
-           p1:= univariate eval(leadpol,lvar,lval) * pol
-           result:= cons((p1 exquo leadingCoefficient pol)::SUP,result)
-        reverse result
- 
-    --Compute the gcd between not coprime polynomials
-      notCoprime(g:SUPP,p2:SUPP,ldeg:List NNI,lvar1:List OV,ltry:List List R) : SUPP ==
-        g1:=gcd(g,differentiate g)
-        l1 := (g exquo g1)::SUPP
-        lg:LGcd:=localgcd(l1,p2,lvar1,ltry)
-        (l,ltry):=(lg.locgcd,lg.goodint)
-        lval:=ltry.first
-        p2l:=(p2 exquo l)::SUPP
-        (gd1,gd2):=(l,l)
-        ul:=completeEval(l,lvar1,lval)
-        dl:=degree ul
-        if degree gcd(ul,differentiate ul) ^=0 then
-          newchoice:=good(l,lvar1,ltry)
-          ul:=newchoice.upol
-          ltry:=newchoice.inval
-          lval:=ltry.first
-        ug1:=completeEval(g1,lvar1,lval)
-        ulist:=[ug1,completeEval(p2l,lvar1,lval)]
-        lcpol:List P:=[leadingCoefficient g1, leadingCoefficient p2]
-        while true repeat
-          d:SUP:=gcd(cons(ul,ulist))
-          if degree d =0 then return gd1
-          lquo:=(ul exquo d)::SUP
-          if degree lquo ^=0 then
-            lgcd:=gcd(cons(leadingCoefficient l,lcpol))
-            (gdl:=lift(l,d,lquo,lgcd,lvar1,ldeg,lval)) case "failed" =>
-               return notCoprime(g,p2,ldeg,lvar1,ltry)
-            l:=gd2:=gdl::SUPP
-            ul:=completeEval(l,lvar1,lval)
-            dl:=degree ul
-          gd1:=gd1*gd2
-          ulist:=[(uf exquo d)::SUP for uf in ulist]
- 
-      gcdPrimitive(p1:SUPP,p2:SUPP) : SUPP ==
-        if (d1:=degree(p1)) > (d2:=degree(p2)) then
-            (p1,p2):= (p2,p1)
-            (d1,d2):= (d2,d1)
-        degree p1 = 0 =>
-            p1 = 0 => unitCanonical p2
-            unitCanonical p1
-        lvar:List OV:=sort(#1>#2,setUnion(variables p1,variables p2))
-        empty? lvar =>
-           raisePolynomial(gcd(lowerPolynomial p1,lowerPolynomial p2))
-        (p2 exquo p1) case SUPP => unitCanonical p1
-        ltry:List List R:=empty()
-        totResult:=localgcd(p1,p2,lvar,ltry)
-        result: SUPP:=totResult.locgcd
-        -- special cases
-        result=1 => 1$SUPP
-<<bmtfix>>
-        while failtest(result,p1,p2) repeat
---        SAY$Lisp  "retrying gcd"
-          ltry:=totResult.goodint
-          totResult:=localgcd(p1,p2,lvar,ltry)
-          result:=totResult.locgcd
-        result
- 
-    --local function for the gcd : it returns the evaluation point too
-      localgcd(p1:SUPP,p2:SUPP,lvar:List(OV),ltry:List List R) : LGcd ==
-        uterm:=chooseVal(p1,p2,lvar,ltry)::UTerm
-        ltry:=uterm.lint
-        listpol:= uterm.lpol
-        ud:=listpol.first
-        dd:= degree ud
- 
-        --the univariate gcd is 1
-        dd=0 => [1$SUPP,ltry]$LGcd
- 
-        --one of the polynomials is the gcd
-        dd=degree(p1) or dd=degree(p2) =>
-                         [uterm.mpol,ltry]$LGcd
-        ldeg:List NNI:=map(min,degree(p1,lvar),degree(p2,lvar))
- 
-       -- if there is a polynomial g s.t. g/gcd and gcd are coprime ...
-        -- I can lift
-        (h:=lift?(p1,p2,uterm,ldeg,lvar)) case notCoprime =>
-          [notCoprime(p1,p2,ldeg,lvar,ltry),ltry]$LGcd
-        h case failed => localgcd(p1,p2,lvar,ltry) -- skip bad values?
-        [h.s,ltry]$LGcd
- 
- 
-  -- content, internal functions return the poly if it is a monomial
-      monomContent(p:SUPP):SUPP ==
-        degree(p)=0 => 1
-        md:= minimumDegree(p)
-        monomial(gcd sort(better,coefficients p),md)
- 
-  -- Ordering for gcd purposes
-      better(p1:P,p2:P):Boolean ==
-        ground? p1 => true
-        ground? p2 => false
-        degree(p1,mainVariable(p1)::OV) < degree(p2,mainVariable(p2)::OV)
- 
-  -- Gcd between polynomial p1 and p2 with
-  -- mainVariable p1 < x=mainVariable p2
-      gcdTermList(p1:P,p2:P) : P ==
-        termList:=sort(better,
-           cons(p1,coefficients univariate(p2,(mainVariable p2)::OV)))
-        q:P:=termList.first
-        for term in termList.rest until q = 1$P repeat q:= gcd(q,term)
-        q
- 
-  -- Gcd between polynomials with the same mainVariable
-      gcd(p1:SUPP,p2:SUPP): SUPP ==
-        if degree(p1) > degree(p2) then (p1,p2):= (p2,p1)
-        degree p1 = 0 =>
-           p1 = 0 => unitCanonical p2
-           p1 = 1 => unitCanonical p1
-           gcd(leadingCoefficient p1, content p2)::SUPP
-        reductum(p1)=0 => gcdMonom(p1,monomContent p2)
-        c1:= monomContent(p1)
-        reductum(p2)=0 => gcdMonom(c1,p2)
-        c2:= monomContent(p2)
-        p1:= (p1 exquo c1)::SUPP
-        p2:= (p2 exquo c2)::SUPP
-        gcdPrimitive(p1,p2) * gcdMonom(c1,c2)
- 
-   -- gcd between 2 monomials
-      gcdMonom(m1:SUPP,m2:SUPP):SUPP ==
-        monomial(gcd(leadingCoefficient(m1),leadingCoefficient(m2)),
-                 min(degree(m1),degree(m2)))
-
- 
-    --If there is a pol s.t. pol/gcd and gcd are coprime I can lift
-      lift?(p1:SUPP,p2:SUPP,uterm:UTerm,ldeg:List NNI,
-                     lvar:List OV) : Union(s:SUPP,failed:"failed",notCoprime:"notCoprime") ==
-        leadpol:Boolean:=false
-        (listpol,lval):=(uterm.lpol,uterm.lint.first)
-        d:=listpol.first
-        listpol:=listpol.rest
-        nolift:Boolean:=true
-        for uf in listpol repeat
-              --note uf and d not necessarily primitive
-          degree gcd(uf,d) =0 => nolift:=false
-        nolift => ["notCoprime"]
-        f:SUPP:=([p1,p2]$List(SUPP)).(position(uf,listpol))
-        lgcd:=gcd(leadingCoefficient p1, leadingCoefficient p2)
-        (l:=lift(f,d,uf,lgcd,lvar,ldeg,lval)) case "failed" => ["failed"]
-        [l :: SUPP]
- 
-   -- interface with the general "lifting" function
-      lift(f:SUPP,d:SUP,uf:SUP,lgcd:P,lvar:List OV,
-                        ldeg:List NNI,lval:List R):Union(SUPP,"failed") ==
-        leadpol:Boolean:=false
-        lcf:P
-        lcf:=leadingCoefficient f
-        df:=degree f
-        leadlist:List(P):=[]
- 
-        if lgcd^=1 then
-          leadpol:=true
-          f:=lgcd*f
-          ldeg:=[n0+n1 for n0 in ldeg for n1 in degree(lgcd,lvar)]
-          lcd:R:=leadingCoefficient d
-          if degree(lgcd)=0 then d:=((retract lgcd) *d exquo lcd)::SUP
-          else d:=(retract(eval(lgcd,lvar,lval)) * d exquo lcd)::SUP
-          uf:=lcd*uf
-        leadlist:=[lgcd,lcf]
-        lg:=imposelc([d,uf],lvar,lval,leadlist)
-        (pl:=lifting(f,lvar,lg,lval,leadlist,ldeg,pmod)) case "failed" =>
-               "failed"
-        plist := pl :: List SUPP
-        (p0:SUPP,p1:SUPP):=(plist.first,plist.2)
-        if completeEval(p0,lvar,lval) ^= lg.first then
-           (p0,p1):=(p1,p0)
-        ^leadpol => p0
-        p0 exquo content(p0)
- 
-  -- Gcd for two multivariate polynomials
-      gcd(p1:P,p2:P) : P ==
-        ground? p1 =>
-          p1 := unitCanonical p1
-          p1 = 1$P => p1
-          p1 = 0$P => unitCanonical p2
-          ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
-          gcdTermList(p1,p2)
-        ground? p2 =>
-          p2 := unitCanonical p2
-          p2 = 1$P => p2
-          p2 = 0$P => unitCanonical p1
-          gcdTermList(p2,p1)
-        (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
-        mv1:= mainVariable(p1)::OV
-        mv2:= mainVariable(p2)::OV
-        mv1 = mv2 => multivariate(gcd(univariate(p1,mv1),
-                                      univariate(p2,mv1)),mv1)
-        mv1 < mv2 => gcdTermList(p1,p2)
-        gcdTermList(p2,p1)
- 
-  -- Gcd for a list of multivariate polynomials
-      gcd(listp:List P) : P ==
-        lf:=sort(better,listp)
-        f:=lf.first
-        for g in lf.rest repeat
-          f:=gcd(f,g)
-          if f=1$P then return f
-        f
-
-      gcd(listp:List SUPP) : SUPP ==
-        lf:=sort(degree(#1)<degree(#2),listp)
-        f:=lf.first
-        for g in lf.rest repeat
-          f:=gcd(f,g)
-          if f=1 then return f
-        f
-
- 
-   -- Gcd for primitive polynomials
-      gcdPrimitive(p1:P,p2:P):P ==
-        (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
-        ground? p1 =>
-          ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
-          p1 = 0$P => p2
-          1$P
-        ground? p2 =>
-          p2 = 0$P => p1
-          1$P
-        mv1:= mainVariable(p1)::OV
-        mv2:= mainVariable(p2)::OV
-        mv1 = mv2 =>
-          md:=min(minimumDegree(p1,mv1),minimumDegree(p2,mv2))
-          mp:=1$P
-          if md>1 then
-            mp:=(mv1::P)**md
-            p1:=(p1 exquo mp)::P
-            p2:=(p2 exquo mp)::P
-          up1 := univariate(p1,mv1)
-          up2 := univariate(p2,mv2)
-          mp*multivariate(gcdPrimitive(up1,up2),mv1)
-        1$P
- 
-  -- Gcd for a list of primitive multivariate polynomials
-      gcdPrimitive(listp:List P) : P ==
-        lf:=sort(better,listp)
-        f:=lf.first
-        for g in lf.rest repeat
-          f:=gcdPrimitive(f,g)
-          if f=1$P then return f
-        f
-
-@
-\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 PGCD PolynomialGcdPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pgrobner.spad.pamphlet b/src/algebra/pgrobner.spad.pamphlet
deleted file mode 100644
index c90a46d..0000000
--- a/src/algebra/pgrobner.spad.pamphlet
+++ /dev/null
@@ -1,121 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pgrobner.spad}
-\author{Patrizia Gianni}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PGROEB PolyGroebner}
-<<package PGROEB PolyGroebner>>=
-)abbrev package PGROEB PolyGroebner
-++ Author: P. Gianni
-++ Date Created: Summer 1988
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors: GroebnerPackage
-++ Also See:
-++ AMS Classifications:
-++ Keywords: groebner basis, polynomial ideals
-++ References:
-++ Description:
-++ Groebner functions for P F
-++   This package is an interface package to the groebner basis
-++ package which allows you to compute groebner bases for polynomials
-++ in either lexicographic ordering or total degree ordering refined
-++ by reverse lex. The input is the ordinary polynomial type which
-++ is internally converted to a type with the required ordering. 
-++ The resulting grobner basis is converted back to ordinary polynomials.
-++ The ordering among the variables is controlled by an explicit list
-++ of variables which is passed as a second argument. The coefficient
-++ domain is allowed to be any gcd domain, but the groebner basis is
-++ computed as if the polynomials were over a field.
- 
-PolyGroebner(F) : C == T
- 
- where
-  F      :   GcdDomain
-  NNI    ==>  NonNegativeInteger
-  P      ==>  Polynomial F
-  L      ==>  List
-  E      ==>  Symbol
- 
-  C == with
-     lexGroebner   :    (L P,L E)  ->  L P
-       ++ lexGroebner(lp,lv) computes Groebner basis
-       ++ for the list of polynomials lp in lexicographic order.
-       ++ The variables are ordered by their position in the list lv.
- 
-     totalGroebner :    (L P, L E) ->  L P
-       ++ totalGroebner(lp,lv) computes Groebner basis
-       ++ for the list of polynomials lp with the terms
-       ++ ordered first by total degree and then
-       ++ refined by reverse lexicographic ordering.
-       ++ The variables are ordered by their position in the list lv.
- 
-  T == add
-     lexGroebner(lp: L P,lv:L E) : L P ==
-       PP:=  PolToPol(lv,F)
-       DPoly := DistributedMultivariatePolynomial(lv,F)
-       DP:=DirectProduct(#lv,NNI)
-       OV:=OrderedVariableList lv
-       b:L DPoly:=[pToDmp(pol)$PP for pol in lp]
-       gb:L DPoly :=groebner(b)$GroebnerPackage(F,DP,OV,DPoly)
-       [dmpToP(pp)$PP for pp in gb]
- 
-     totalGroebner(lp: L P,lv:L E) : L P ==
-       PP:=  PolToPol(lv,F)
-       HDPoly := HomogeneousDistributedMultivariatePolynomial(lv,F)
-       HDP:=HomogeneousDirectProduct(#lv,NNI)
-       OV:=OrderedVariableList lv
-       b:L HDPoly:=[pToHdmp(pol)$PP for pol in lp]
-       gb:=groebner(b)$GroebnerPackage(F,HDP,OV,HDPoly)
-       [hdmpToP(pp)$PP for pp in gb]
-
-@
-\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 PGROEB PolyGroebner>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pinterp.spad.pamphlet b/src/algebra/pinterp.spad.pamphlet
deleted file mode 100644
index d8c1482..0000000
--- a/src/algebra/pinterp.spad.pamphlet
+++ /dev/null
@@ -1,111 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pinterp.spad}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PINTERPA PolynomialInterpolationAlgorithms}
-<<package PINTERPA PolynomialInterpolationAlgorithms>>=
-)abbrev package PINTERPA PolynomialInterpolationAlgorithms
-++ Description:
-++ This package exports interpolation algorithms
-PolynomialInterpolationAlgorithms(F, P): Cat == Body   where
-    F: Field
-    P: UnivariatePolynomialCategory(F)
- 
-    Cat ==> with
-        LagrangeInterpolation: (List F, List F) -> P
-		++ LagrangeInterpolation(l1,l2) \undocumented
- 
-    Body ==> add
-        LagrangeInterpolation(lx, ly) ==
-            #lx ^= #ly =>
-                error "Different number of points and values."
-            ip: P := 0
-            for xi in lx for yi in ly for i in 0.. repeat
-                pp: P := 1
-                xp: F := 1
-                for xj in lx for j in 0.. | i ^= j repeat
-                    pp := pp * (monomial(1,1) - monomial(xj,0))
-                    xp := xp * (xi - xj)
-                ip := ip + (yi/xp) * pp
-            ip
-
-@
-\section{package PINTERP PolynomialInterpolation}
-<<package PINTERP PolynomialInterpolation>>=
-)abbrev package PINTERP PolynomialInterpolation
-++ Description:
-++ This package exports interpolation algorithms
-PolynomialInterpolation(xx, F): Cat == Body   where
-    xx: Symbol
-    F:  Field
-    UP  ==> UnivariatePolynomial
-    SUP ==> SparseUnivariatePolynomial
- 
-    Cat ==> with
-        interpolate: (UP(xx,F), List F, List F) -> UP(xx,F)
-		++ interpolate(u,lf,lg) \undocumented
-        interpolate: (List F, List F)           -> SUP F
-		++ interpolate(lf,lg) \undocumented
- 
-    Body ==> add
-        PIA ==> PolynomialInterpolationAlgorithms
- 
-        interpolate(qx, lx, ly) ==
-            px := LagrangeInterpolation(lx, ly)$PIA(F, UP(xx, F))
-            elt(px, qx)
- 
-        interpolate(lx, ly) ==
-            LagrangeInterpolation(lx, ly)$PIA(F, SUP F)
-
-@
-\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 PINTERPA PolynomialInterpolationAlgorithms>>
-<<package PINTERP PolynomialInterpolation>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pleqn.spad.pamphlet b/src/algebra/pleqn.spad.pamphlet
deleted file mode 100644
index 8b0569f..0000000
--- a/src/algebra/pleqn.spad.pamphlet
+++ /dev/null
@@ -1,654 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pleqn.spad}
-\author{William Sit}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\begin{verbatim}
-++ This package completely solves a parametric linear system of equations
-++ by decomposing the set of all parametric values for which the linear
-++ system is consistent into a union of quasi-algebraic  sets (which need
-++ not be irredundant, but most of the time is). Each quasi-algebraic
-++ set is described by a list of polynomials that vanish on the set, and
-++ a list of polynomials that vanish at no point of the set.
-++ For each quasi-algebraic set, the solution of the linear system
-++ is given, as a particular solution and  a basis of the homogeneous
-++ system.
-++ The parametric linear system should be given in matrix form, with
-++ a coefficient matrix and a right hand side vector. The entries
-++ of the coefficient matrix and right hand side vector should be
-++ polynomials in the parametric variables, over a Euclidean domain
-++ of characteristic zero.
-++
-++ If the system is homogeneous, the right hand side need not be given.
-++ The right hand side can also be  replaced by an indeterminate vector,
-++ in which case, the conditions required for consistency will also be
-++ given.
-++
-++ The package has other facilities for saving results to external
-++ files, as well as solving the system for a specified minimum rank.
-++ Altogether there are 12 mode maps for psolve, as explained below.
-
--- modified to conform with new runtime system 06/04/90
--- updated with comments for MB, 02/16/94
--- also cleaned up some unnecessary arguments in regime routine
---
--- MB: In order to allow the rhs to be indeterminate, while working
--- mainly with the parametric variables on the lhs (less number of
--- variables), certain conversions of internal representation from
--- GR to Polynomial R and Fraction Polynomial R are done.  At the time
--- of implementation, I thought that this may be more efficient.  I
--- have not done any comparison since that requires rewriting the
--- package.  My own application needs to call this package quite often,
--- and most computations involves only polynomials in the parametric
--- variables.
-
--- The 12 modes of psolve are probably not all necessary.  Again, I
--- was thinking that if there are many regimes and many ranks, then
--- the output is quite big, and it may be nice to be able to save it
--- and read the results in later to continue computing rather than
--- recomputing.  Because of the combinatorial nature of the algorithm
--- (computing all subdeterminants!), it does not take a very big matrix
--- to get into many regimes.  But I now have second thoughts of this
--- design, since most of the time, the results are just intermediate,
--- passed to be further processed.  On the other hand, there is probably
--- no penalty in leaving the options as is.
-\end{verbatim}
-\section{package PLEQN ParametricLinearEquations}
-<<package PLEQN ParametricLinearEquations>>=
-)abbrev package PLEQN ParametricLinearEquations
-++  Author: William Sit, spring 89
-ParametricLinearEquations(R,Var,Expon,GR):
-            Declaration == Definition where
-
-  R         :  Join(EuclideanDomain, CharacteristicZero)
-  -- Warning: does not work if R is a field! because of Fraction R
-  Var       :  Join(OrderedSet,ConvertibleTo (Symbol))
-  Expon     :  OrderedAbelianMonoidSup
-  GR        :  PolynomialCategory(R,Expon,Var)
-  F        == Fraction R
-  FILE ==> FileCategory
-  FNAME ==> FileName
-  GB  ==> EuclideanGroebnerBasisPackage
---  GBINTERN ==> GroebnerInternalPackage
-  I   ==> Integer
-  L   ==> List
-  M   ==> Matrix
-  NNI ==> NonNegativeInteger
-  OUT ==> OutputForm
-  P   ==> Polynomial
-  PI  ==> PositiveInteger
-  SEG ==> Segment
-  SM  ==> SquareMatrix
-  S   ==> String
-  V   ==> Vector
-  mf    ==> MultivariateFactorize(Var,Expon,R,GR)
-  rp    ==> GB(R,Expon,Var,GR)
-  gb    ==> GB(R,Expon,Var,GR)
-  PR    ==> P R
-  GF    ==> Fraction PR
-  plift ==> PolynomialCategoryLifting(Expon,Var,R,GR,GF)
-  Inputmode ==> Integer
-  groebner ==> euclideanGroebner
-  redPol  ==> euclideanNormalForm
-
--- MB: The following macros are data structures to store mostly
--- intermediate results
--- Rec stores a subdeterminant with corresponding row and column indices
--- Fgb is a Groebner basis for the ideal generated by the subdeterminants
---     of a given rank.
--- Linsys specifies a linearly independent system of a given system
---     assuming a given rank, using given row and column indices
--- Linsoln stores the solution to the parametric linear system as a basis
---     and a particular solution (for a given regime)
--- Rec2 stores the rank, and a list of subdeterminants of that rank,
---     and a Groebner basis for the ideal they generate.
--- Rec3 stores a regime and the corresponding solution; the regime is
---     given by a list of equations (eqzro) and one inequation (neqzro)
---     describing the quasi-algebraic set which is the regime; the
---     additional consistency conditions due to the rhs is given by wcond.
--- Ranksolns stores a list of regimes and their solutions, and the number
---     of regimes all together.
--- Rec8 (temporary) stores a quasi-algebraic set with an indication
--- whether it is empty (sysok = false) or not (sysok = true).
-
--- I think psolve should be renamed parametricSolve, or even
--- parametricLinearSolve.  On the other hand, may be just solve will do.
--- Please feel free to change it to conform with system conventions.
--- Most psolve routines return a list of regimes and solutions,
--- except those that output to file when the number of regimes is
--- returned instead.
--- This version has been tested on the pc version 1.608 March 13, 1992
-
-  Rec   ==> Record(det:GR,rows:L I,cols:L I)
-  Eqns  ==> L Rec
-  Fgb   ==> L GR  -- groebner basis
-  Linsoln   ==> Record(partsol:V GF,basis:L V GF)
-  Linsys    ==> Record(mat:M GF,vec:L GF,rank:NNI,rows:L I,cols:L I)
-  Rec2  ==> Record(rank:NNI,eqns:Eqns,fgb:Fgb)
-  RankConds ==> L Rec2
-  Rec3  ==> Record(eqzro:L GR, neqzro:L GR,wcond:L PR, bsoln:Linsoln)
-  Ranksolns ==> Record(rgl:L Rec3,rgsz:I)
-  Rec8 ==> Record(sysok:Boolean, z0:L GR, n0:L GR)
-
-
-  Declaration == with
-      psolve: (M GR, L GR) -> L Rec3
-        ++ psolve(c,w) solves c z = w for all possible ranks
-        ++ of the matrix c and given right hand side vector w
-        -- this is mode 1
-      psolve: (M GR, L Symbol) -> L Rec3
-        ++ psolve(c,w) solves c z = w for all possible ranks
-        ++ of the matrix c and indeterminate right hand side w
-        -- this is mode 2
-      psolve:  M GR        -> L Rec3
-        ++ psolve(c) solves the homogeneous linear system
-        ++ c z = 0 for all possible ranks of the matrix c
-        -- this is mode 3
-      psolve: (M GR, L GR, PI) -> L Rec3
-        ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
-        ++ of the matrix c and given right hand side vector w
-        -- this is mode 4
-      psolve: (M GR, L Symbol, PI) -> L Rec3
-        ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
-        ++ of the matrix c and indeterminate right hand side w
-        -- this is mode 5
-      psolve: (M GR,       PI) -> L Rec3
-        ++ psolve(c) solves the homogeneous linear system
-        ++ c z = 0 for all possible ranks >= k of the matrix c
-        -- this is mode 6
-      psolve: (M GR, L GR, S) -> I
-        ++ psolve(c,w,s) solves c z = w for all possible ranks
-        ++ of the matrix c and given right hand side vector w,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 7
-      psolve: (M GR, L Symbol, S) -> I
-        ++ psolve(c,w,s) solves c z = w for all possible ranks
-        ++ of the matrix c and indeterminate right hand side w,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 8
-      psolve: (M GR,       S) -> I
-        ++ psolve(c,s) solves c z = 0 for all possible ranks
-        ++ of the matrix c and given right hand side vector w,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 9
-      psolve: (M GR, L GR, PI, S) -> I
-        ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
-        ++ of the matrix c and given right hand side w,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 10
-      psolve: (M GR, L Symbol, PI, S) -> I
-        ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
-        ++ of the matrix c and indeterminate right hand side w,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 11
-      psolve: (M GR,       PI, S) -> I
-        ++ psolve(c,k,s) solves c z = 0 for all possible ranks >= k
-        ++ of the matrix c,
-        ++ writes the results to a file named s, and returns the
-        ++ number of regimes
-        -- this is mode 12
-
-      wrregime   : (L Rec3, S) -> I
-        ++ wrregime(l,s) writes a list of regimes to a file named s
-        ++ and returns the number of regimes written
-      rdregime   : S -> L Rec3
-        ++ rdregime(s) reads in a list from a file with name s
-
-        -- for internal use only --
-      -- these are exported so my other packages can use them
-
-      bsolve: (M GR, L GF, NNI, S, Inputmode) -> Ranksolns
-        ++ bsolve(c, w, r, s, m) returns a list of regimes and
-        ++ solutions of the system c z = w for ranks at least r;
-        ++ depending on the mode m chosen, it writes the output to
-        ++ a file given by the string s.
-      dmp2rfi: GR -> GF
-        ++ dmp2rfi(p) converts p to target domain
-      dmp2rfi: M GR -> M GF
-        ++ dmp2rfi(m) converts m to target domain
-      dmp2rfi: L GR -> L GF
-        ++ dmp2rfi(l) converts l to target domain
-      se2rfi:  L Symbol -> L GF
-        ++ se2rfi(l) converts l to target domain
-      pr2dmp: PR -> GR
-        ++ pr2dmp(p) converts p to target domain
-      hasoln: (Fgb, L GR) -> Rec8
-        ++ hasoln(g, l) tests whether the quasi-algebraic set
-        ++ defined by p = 0 for p in g and q ^= 0 for q in l
-        ++ is empty or not and returns a simplified definition
-        ++ of the quasi-algebraic set
-        -- this is now done in QALGSET package
-      ParCondList: (M GR,NNI) -> RankConds
-        ++ ParCondList(c,r) computes a list of subdeterminants of each
-        ++ rank >= r of the matrix c and returns
-        ++ a groebner basis for the
-        ++ ideal they generate
-      redpps: (Linsoln, Fgb) -> Linsoln
-        ++ redpps(s,g) returns the simplified form of s after reducing
-        ++ modulo a groebner basis g
-
-
-
---               L O C A L    F U N C T I O N S
-
-      B1solve: Linsys -> Linsoln
-        ++ B1solve(s) solves the system (s.mat) z = s.vec
-        ++ for the variables given by the column indices of s.cols
-        ++ in terms of the other variables and the right hand side s.vec
-        ++ by assuming that the rank is s.rank,
-        ++ that the system is consistent, with the linearly
-        ++ independent equations indexed by the given row indices s.rows;
-        ++ the coefficients in s.mat involving parameters are treated as
-        ++ polynomials.  B1solve(s) returns a particular solution to the
-        ++ system and a basis of the homogeneous system (s.mat) z = 0.
-      factorset: GR -> L GR
-        ++ factorset(p) returns the set of irreducible factors of p.
-      maxrank: RankConds -> NNI
-        ++ maxrank(r) returns the maximum rank in the list r of regimes
-      minrank: RankConds -> NNI
-        ++ minrank(r) returns the minimum rank in the list r of regimes
-      minset: L L GR -> L L GR
-        ++ minset(sl) returns the sublist of sl consisting of the minimal
-        ++ lists (with respect to inclusion) in the list sl of lists
-      nextSublist: (I, I) -> L L I
-        ++ nextSublist(n,k) returns a list of k-subsets of {1, ..., n}.
-      overset?: (L GR, L L GR) -> Boolean
-        ++ overset?(s,sl) returns true if s properly a sublist of a member
-        ++ of sl; otherwise it returns false
-      ParCond    : (M GR,NNI) -> Eqns
-        ++ ParCond(m,k) returns the list of all k by k subdeterminants in
-        ++ the matrix m
-      redmat: (M GR, Fgb) -> M GR
-        ++ redmat(m,g) returns a matrix whose entries are those of m
-        ++ modulo the ideal generated by the groebner basis g
-      regime: (Rec,M GR,L GF,L L GR,NNI,NNI,Inputmode) -> Rec3
-        ++ regime(y,c, w, p, r, rm, m) returns a regime,
-        ++ a list of polynomials specifying the consistency conditions,
-        ++ a particular solution and basis representing the general
-        ++ solution of the parametric linear system c z = w
-        ++ on that regime. The regime returned depends on
-        ++ the subdeterminant y.det and the row and column indices.
-        ++ The solutions are simplified using the assumption that
-        ++ the system has rank r and maximum rank rm. The list p
-        ++ represents a list of list of factors of polynomials in
-        ++ a groebner basis of the ideal generated by higher order
-        ++ subdeterminants, and ius used for the simplification.
-        ++ The mode m
-        ++ distinguishes the cases when the system is homogeneous,
-        ++ or the right hand side is arbitrary, or when there is no
-        ++ new right hand side variables.
-      sqfree: GR -> GR
-        ++ sqfree(p) returns the product of square free factors of p
-      inconsistent?: L GR -> Boolean
-        ++ inconsistant?(pl) returns true if the system of equations
-        ++ p = 0 for p in pl is inconsistent.  It is assumed
-        ++ that pl is a groebner basis.
-        -- this is needed because of change to
-        -- EuclideanGroebnerBasisPackage
-      inconsistent?: L PR -> Boolean
-        ++ inconsistant?(pl) returns true if the system of equations
-        ++ p = 0 for p in pl is inconsistent.  It is assumed
-        ++ that pl is a groebner basis.
-        -- this is needed because of change to
-        -- EuclideanGroebnerBasisPackage
-
-  Definition == add
-
-    inconsistent?(pl:L GR):Boolean ==
-      for p in pl repeat
-        ground? p => return true
-      false
-    inconsistent?(pl:L PR):Boolean ==
-      for p in pl repeat
-        ground? p => return true
-      false
-
-    B1solve (sys:Linsys):Linsoln ==
-      i,j,i1,j1:I
-      rss:L I:=sys.rows
-      nss:L I:=sys.cols
-      k:=sys.rank
-      cmat:M GF:=sys.mat
-      n:=ncols cmat
-      frcols:L I:=setDifference$(L I) (expand$(SEG I) (1..n), nss)
-      w:L GF:=sys.vec
-      p:V GF:=new(n,0)
-      pbas:L V GF:=[]
-      if k ^= 0 then
-        augmat:M GF:=zero(k,n+1)
-        for i in rss for i1 in 1.. repeat
-          for j in nss for j1 in 1.. repeat
-            augmat(i1,j1):=cmat(i,j)
-          for j in frcols for j1 in k+1.. repeat
-            augmat(i1,j1):=-cmat(i,j)
-          augmat(i1,n+1):=w.i
-        augmat:=rowEchelon$(M GF) augmat
-        for i in nss for i1 in 1.. repeat p.i:=augmat(i1,n+1)
-        for j in frcols for j1 in k+1.. repeat
-          pb:V GF:=new(n,0)
-          pb.j:=1
-          for i in nss for i1 in 1.. repeat
-            pb.i:=augmat(i1,j1)
-          pbas:=cons(pb,pbas)
-      else
-        for j in frcols for j1 in k+1.. repeat
-          pb:V GF:=new(n,0)
-          pb.j:=1
-          pbas:=cons(pb,pbas)
-      [p,pbas]
-
-    regime (y, coef, w, psbf, rk, rkmax, mode) ==
-      i,j:I
-      -- use the y.det nonzero to simplify the groebner basis
-      -- of ideal generated by higher order subdeterminants
-      ydetf:L GR:=factorset y.det
-      yzero:L GR:=
-        rk = rkmax => nil$(L GR)
-        psbf:=[setDifference(x, ydetf) for x in psbf]
-        groebner$gb [*/x for x in psbf]
-      -- simplify coefficients by modulo ideal
-      nc:M GF:=dmp2rfi redmat(coef,yzero)
-      -- solve the system
-      rss:L I:=y.rows;  nss:L I :=y.cols
-      sys:Linsys:=[nc,w,rk,rss,nss]$Linsys
-      pps:= B1solve(sys)
-      pp:=pps.partsol
-      frows:L I:=setDifference$(L I) (expand$(SEG I) (1..nrows coef),rss)
-      wcd:L PR:= []
-      -- case homogeneous rhs
-      entry? (mode, [3,6,9,12]$(L I)) =>
-               [yzero, ydetf,wcd, redpps(pps, yzero)]$Rec3
-      -- case arbitrary rhs, pps not reduced
-      for i in frows repeat
-          weqn:GF:=+/[nc(i,j)*(pp.j) for j in nss]
-          wnum:PR:=numer$GF (w.i - weqn)
-          wnum = 0 => "trivially satisfied"
-          ground? wnum => return [yzero, ydetf,[1$PR]$(L PR),pps]$Rec3
-          wcd:=cons(wnum,wcd)
-      entry? (mode, [2,5,8,11]$(L I)) => [yzero, ydetf, wcd, pps]$Rec3
-      -- case no new rhs variable
-      if not empty? wcd then _
-        yzero:=removeDuplicates append(yzero,[pr2dmp pw for pw in wcd])
-      test:Rec8:=hasoln (yzero, ydetf)
-      not test.sysok => [test.z0, test.n0, [1$PR]$(L PR), pps]$Rec3
-      [test.z0, test.n0, [], redpps(pps, test.z0)]$Rec3
-
-    bsolve (coeff, w, h, outname, mode) ==
-      r:=nrows coeff
---    n:=ncols coeff
-      r ^= #w => error "number of rows unequal on lhs and rhs"
-      newfile:FNAME
-      rksoln:File Rec3
-      count:I:=0
-      lrec3:L Rec3:=[]
-      filemode:Boolean:= entry? (mode, [7,8,9,10,11,12]$(L I))
-      if filemode then
-        newfile:=new$FNAME  ("",outname,"regime")
-        rksoln:=open$(File Rec3) newfile
-      y:Rec
-      k:NNI
-      rrcl:RankConds:=
-        entry? (mode,[1,2,3,7,8,9]$(L I)) => ParCondList (coeff,0)
-        entry? (mode,[4,5,6,10,11,12]$(L I)) => ParCondList (coeff,h)
-      rkmax:=maxrank rrcl
-      rkmin:=minrank rrcl
-      for k in rkmax-rkmin+1..1 by -1 repeat
-        rk:=rrcl.k.rank
-        pc:Eqns:=rrcl.k.eqns
-        psb:Fgb:= (if rk=rkmax then [] else rrcl.(k+1).fgb)
-        psbf:L L GR:= [factorset x for x in psb]
-        psbf:= minset(psbf)
-        for y in pc repeat
-          rec3:Rec3:= regime (y, coeff, w, psbf, rk, rkmax, mode)
-          inconsistent? rec3.wcond => "incompatible system"
-          if filemode then write_!(rksoln, rec3)
-          else lrec3:= cons(rec3, lrec3)
-          count:=count+1
-      if filemode then close_! rksoln
-      [lrec3, count]$Ranksolns
-
-    factorset y ==
-      ground? y => []
-      [j.factor for j in factors(factor$mf y)]
-
-    ParCondList (mat, h) ==
-      rcl: RankConds:= []
-      ps: L GR:=[]
-      pc:Eqns:=[]
-      npc: Eqns:=[]
-      psbf: Fgb:=[]
-      rc: Rec
-      done: Boolean := false
-      r:=nrows mat
-      n:=ncols mat
-      maxrk:I:=min(r,n)
-      k:NNI
-      for k in min(r,n)..h by -1 until done repeat
-        pc:= ParCond(mat,k)
-        npc:=[]
-        (empty? pc) and (k >= 1) => maxrk:= k - 1
-        if ground? pc.1.det -- only one is sufficient (neqzro = {})
-        then (npc:=pc; done:=true; ps := [1$GR])
-        else
-          zro:L GR:= (if k = maxrk then [] else rcl.1.fgb)
-          covered:Boolean:=false
-          for rc in pc until covered repeat
-            p:GR:= redPol$rp (rc.det, zro)
-            p = 0 => "incompatible or covered subdeterminant"
-            test:=hasoln(zro, [rc.det])
---          zroideal:=ideal(zro)
---          inRadical? (p, zroideal) => "incompatible or covered"
-            ^test.sysok => "incompatible or covered"
--- The next line is WRONG! cannot replace zro by test.z0
---          zro:=groebner$gb (cons(*/test.n0, test.z0))
-            zro:=groebner$gb (cons(p,zro))
-            npc:=cons(rc,npc)
-            done:= covered:= inconsistent? zro
-          ps:=zro
-        pcl: Rec2:= construct(k,npc,ps)
-        rcl:=cons(pcl,rcl)
-      rcl
-
-    redpps(pps, zz) ==
-      pv:=pps.partsol
-      r:=#pv
-      pb:=pps.basis
-      n:=#pb + 1
-      nummat:M GR:=zero(r,n)
-      denmat:M GR:=zero(r,n)
-      for i in  1..r repeat
-        nummat(i,1):=pr2dmp numer$GF pv.i
-        denmat(i,1):=pr2dmp denom$GF pv.i
-      for j in 2..n repeat
-        for i in 1..r  repeat
-          nummat(i,j):=pr2dmp numer$GF (pb.(j-1)).i
-          denmat(i,j):=pr2dmp denom$GF (pb.(j-1)).i
-      nummat:=redmat(nummat, zz)
-      denmat:=redmat(denmat, zz)
-      for i in 1..r repeat
-        pv.i:=(dmp2rfi nummat(i,1))/(dmp2rfi denmat(i,1))
-      for j in 2..n repeat
-        pbj:V GF:=new(r,0)
-        for i in 1..r repeat
-          pbj.i:=(dmp2rfi nummat(i,j))/(dmp2rfi  denmat(i,j))
-        pb.(j-1):=pbj
-      [pv, pb]
-
-    dmp2rfi (mat:M GR): M GF ==
-      r:=nrows mat
-      n:=ncols mat
-      nmat:M GF:=zero(r,n)
-      for i in 1..r repeat
-        for j in 1..n repeat
-          nmat(i,j):=dmp2rfi mat(i,j)
-      nmat
-
-    dmp2rfi (vl: L GR):L GF ==
-      [dmp2rfi v for v in vl]
-
-    psolve (mat:M GR, w:L GR): L Rec3 ==
-      bsolve(mat, dmp2rfi w, 1, "nofile", 1).rgl
-    psolve (mat:M GR, w:L Symbol): L Rec3 ==
-      bsolve(mat,  se2rfi w, 1, "nofile", 2).rgl
-    psolve (mat:M GR): L Rec3 ==
-      bsolve(mat, [0$GF for i in 1..nrows mat], 1, "nofile", 3).rgl
-
-    psolve (mat:M GR, w:L GR, h:PI): L Rec3 ==
-      bsolve(mat, dmp2rfi w, h::NNI, "nofile", 4).rgl
-    psolve (mat:M GR, w:L Symbol, h:PI): L Rec3 ==
-      bsolve(mat, se2rfi w, h::NNI, "nofile", 5).rgl
-    psolve (mat:M GR, h:PI): L Rec3 ==
-      bsolve(mat, [0$GF for i in 1..nrows mat], h::NNI, "nofile", 6).rgl
-
-    psolve (mat:M GR, w:L GR, outname:S): I ==
-      bsolve(mat, dmp2rfi w, 1, outname, 7).rgsz
-    psolve (mat:M GR, w:L Symbol, outname:S): I ==
-      bsolve(mat, se2rfi w, 1, outname, 8).rgsz
-    psolve (mat:M GR, outname:S): I ==
-      bsolve(mat, [0$GF for i in 1..nrows mat], 1, outname, 9).rgsz
-
-    nextSublist (n,k) ==
-      n <= 0 => []
-      k <= 0 => [ nil$(List Integer) ]
-      k > n => []
-      n = 1 and k = 1 => [[1]]
-      mslist: L L I:=[]
-      for ms in nextSublist(n-1,k-1) repeat
-        mslist:=cons(append(ms,[n]),mslist)
-      append(nextSublist(n-1,k), mslist)
-
-    psolve (mat:M GR, w:L GR, h:PI, outname:S): I ==
-      bsolve(mat, dmp2rfi w, h::NNI, outname, 10).rgsz
-    psolve (mat:M GR, w:L Symbol, h:PI, outname:S): I ==
-      bsolve(mat, se2rfi w, h::NNI, outname, 11).rgsz
-    psolve (mat:M GR, h:PI, outname:S): I ==
-      bsolve(mat,[0$GF for i in 1..nrows mat],h::NNI,outname, 12).rgsz
-
-    hasoln (zro,nzro) ==
-      empty? zro => [true, zro, nzro]
-      zro:=groebner$gb zro
-      inconsistent? zro => [false, zro, nzro]
-      empty? nzro =>[true, zro, nzro]
-      pnzro:GR:=redPol$rp (*/nzro, zro)
-      pnzro = 0 => [false, zro, nzro]
-      nzro:=factorset pnzro
-      psbf:L L GR:= minset [factorset p for p in zro]
-      psbf:= [setDifference(x, nzro) for x in psbf]
-      entry? ([], psbf) => [false, zro, nzro]
-      zro:=groebner$gb [*/x for x in psbf]
-      inconsistent? zro => [false, zro, nzro]
-      nzro:=[redPol$rp (p,zro) for p in nzro]
-      nzro:=[p for p in nzro | ^(ground? p)]
-      [true, zro, nzro]
-
-
-
-    se2rfi w == [coerce$GF monomial$PR (1$PR, wi, 1) for wi in w]
-
-    pr2dmp p ==
-      ground? p => (ground p)::GR
-      algCoerceInteractive(p,PR,GR)$(Lisp) pretend GR
-
-    wrregime (lrec3, outname) ==
-      newfile:FNAME:=new$FNAME ("",outname,"regime")
-      rksoln: File Rec3:=open$(File Rec3) newfile
-      count:I:=0  -- number of distinct regimes
---      rec3: Rec3
-      for rec3 in lrec3 repeat
-          write_!(rksoln, rec3)
-          count:=count+1
-      close_!(rksoln)
-      count
-
-    dmp2rfi (p:GR):GF ==
-      map$plift ((convert #1)@Symbol::GF, #1::PR::GF, p)
-
-
-    rdregime inname ==
-      infilename:=filename$FNAME ("",inname, "regime")
-      infile: File Rec3:=open$(File Rec3) (infilename, "input")
-      rksoln:L Rec3:=[]
-      rec3:Union(Rec3, "failed"):=readIfCan_!$(File Rec3) (infile)
-      while rec3 case Rec3 repeat
-        rksoln:=cons(rec3::Rec3,rksoln) -- replace : to :: for AIX
-        rec3:=readIfCan_!$(File Rec3) (infile)
-      close_!(infile)
-      rksoln
-
-    maxrank rcl ==
-      empty? rcl => 0
-      "max"/[j.rank for j in rcl]
-
-    minrank rcl ==
-      empty? rcl => 0
-      "min"/[j.rank for j in rcl]
-
-    minset lset ==
-      empty? lset => lset
-      [x for x in lset | ^(overset?(x,lset))]
-
-    sqfree p == */[j.factor for j in factors(squareFree p)]
-
-
-    ParCond (mat, k) ==
-      k = 0 => [[1, [], []]$Rec]
-      j:NNI:=k::NNI
-      DetEqn :Eqns := []
-      r:I:= nrows(mat)
-      n:I:= ncols(mat)
-      k > min(r,n) => error "k exceeds maximum possible rank "
-      found:Boolean:=false
-      for rss in nextSublist(r, k) until found repeat
-        for nss in nextSublist(n, k) until found repeat
-          matsub := mat(rss, nss) pretend SM(j, GR)
-          detmat := determinant(matsub)
-          if detmat ^= 0 then
-            found:= (ground? detmat)
-            detmat:=sqfree detmat
-            neweqn:Rec:=construct(detmat,rss,nss)
-            DetEqn:=cons(neweqn, DetEqn)
-      found => [first DetEqn]$Eqns
-      sort(degree #1.det < degree #2.det, DetEqn)
-
-
-
-    overset?(p,qlist) ==
-      empty? qlist => false
-      or/[(brace$(Set GR) q) <$(Set GR) (brace$(Set GR) p) _
-                                                for q in qlist]
-
-
-    redmat (mat,psb) ==
-      i,j:I
-      r:=nrows(mat)
-      n:=ncols(mat)
-      newmat: M GR:=zero(r,n)
-      for i in 1..r repeat
-        for j in 1..n repeat
-          p:GR:=mat(i,j)
-          ground? p => newmat(i,j):=p
-          newmat(i,j):=redPol$rp (p,psb)
-      newmat
-
-@
-<<*>>=
--- See LICENSE.AXIOM for Copyright information
-
-<<package PLEQN ParametricLinearEquations>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/plot.spad.pamphlet b/src/algebra/plot.spad.pamphlet
deleted file mode 100644
index 3250c1d..0000000
--- a/src/algebra/plot.spad.pamphlet
+++ /dev/null
@@ -1,91 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra plot.spad}
-\author{Michael Monagan, Clifton J. Williamson, Jon Steinbach, Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PLOT1 PlotFunctions1}
-<<package PLOT1 PlotFunctions1>>=
-)abbrev package PLOT1 PlotFunctions1
-++ Authors: R.T.M. Bronstein, C.J. Williamson
-++ Date Created: Jan 1989
-++ Date Last Updated: 4 Mar 1990
-++ Basic Operations: plot, plotPolar
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: PlotFunctions1 provides facilities for plotting curves
-++ where functions SF -> SF are specified by giving an expression
-PlotFunctions1(S:ConvertibleTo InputForm): with
-    plot : (S, Symbol, Segment DoubleFloat) -> Plot
-      ++ plot(fcn,x,seg) plots the graph of \spad{y = f(x)} on a interval
-    plot : (S, S, Symbol, Segment DoubleFloat) -> Plot
-      ++ plot(f,g,t,seg) plots the graph of \spad{x = f(t)}, \spad{y = g(t)} as t
-      ++ ranges over an interval.
-    plotPolar : (S, Symbol, Segment DoubleFloat) -> Plot
-      ++ plotPolar(f,theta,seg) plots the graph of \spad{r = f(theta)} as
-      ++ theta ranges over an interval
-    plotPolar : (S, Symbol) -> Plot
-      ++ plotPolar(f,theta) plots the graph of \spad{r = f(theta)} as
-      ++ theta ranges from 0 to 2 pi
-  == add
-    import MakeFloatCompiledFunction(S)
-
-    plot(f, x, xRange) == plot(makeFloatFunction(f, x), xRange)
-    plotPolar(f,theta) == plotPolar(makeFloatFunction(f,theta))
-    plot(f1, f2, t, tRange) ==
-      plot(makeFloatFunction(f1, t), makeFloatFunction(f2, t), tRange)
-    plotPolar(f,theta,thetaRange) ==
-      plotPolar(makeFloatFunction(f,theta),thetaRange)
-
-@
-\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 PLOT1 PlotFunctions1>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/plottool.spad.pamphlet b/src/algebra/plottool.spad.pamphlet
deleted file mode 100644
index adc528a..0000000
--- a/src/algebra/plottool.spad.pamphlet
+++ /dev/null
@@ -1,130 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra plottool.spad}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PLOTTOOL PlotTools}
-<<package PLOTTOOL PlotTools>>=
-)abbrev package PLOTTOOL PlotTools
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Keywords:
-++ Examples:
-++ References:
-++ Description:
-++ This package exports plotting tools 
-PlotTools(): Exports == Implementation where
-  L   ==> List
---  Pt  ==> TwoDimensionalPoint
-  SEG ==> Segment
-  SF  ==> DoubleFloat
-  Pt ==> Point(SF)
-  PLOT ==> Plot 
-  DROP ==> DrawOption
-  S    ==> String
-  VIEW2D ==> TwoDimensionalViewport
-
-  Exports ==> with
-    calcRanges: L L Pt             -> L SEG SF
-	++ calcRanges(l) \undocumented
- 
-  Implementation ==> add
-    import GraphicsDefaults
-    import PLOT
-    import TwoDimensionalPlotClipping
-    import DrawOptionFunctions0
-    import ViewportPackage
-    import POINT
-    import PointPackage(SF)
- 
-    --%Local functions
-    xRange0: L Pt -> SEG SF
-    xRange: L L Pt -> SEG SF
-    yRange0: L Pt -> SEG SF
-    yRange: L L Pt -> SEG SF
-    drawToScaleRanges: (SEG SF,SEG SF) -> L SEG SF
-  
-    drawToScaleRanges(xVals,yVals) ==
-      xDiff := (xHi := hi xVals) - (xLo := lo xVals)
-      yDiff := (yHi := hi yVals) - (yLo := lo yVals)
-      pad := abs(yDiff - xDiff)/2
-      yDiff > xDiff => [segment(xLo - pad,xHi + pad),yVals]
-      [xVals,segment(yLo - pad,yHi + pad)]
- 
-    select : (L Pt,Pt -> SF,(SF,SF) -> SF) -> SF
-    select(l,f,g) ==
-      m := f first l
-      for p in rest l repeat m := g(m,f p)
-      m
- 
-    xRange0(list:L Pt) == select(list,xCoord,min) .. select(list,xCoord,max)
-    yRange0(list:L Pt) == select(list,yCoord,min) .. select(list,yCoord,max)
- 
-    select2: (L L Pt,L Pt -> SF,(SF,SF) -> SF) -> SF
-    select2(l,f,g) ==
-      m := f first l
-      for p in rest l repeat m := g(m,f p)
-      m
- 
-    xRange(list:L L Pt) ==
-      select2(list,lo(xRange0(#1)),min) .. select2(list,hi(xRange0(#1)),max)
- 
-    yRange(list:L L Pt) ==
-      select2(list,lo(yRange0(#1)),min) .. select2(list,hi(yRange0(#1)),max)
-
-  --%Exported Functions
-    calcRanges(llp) ==
-      drawToScale() => drawToScaleRanges(xRange llp, yRange llp)
-      [xRange llp, yRange llp]
-
-@
-\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 PLOTTOOL PlotTools>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/poltopol.spad.pamphlet b/src/algebra/poltopol.spad.pamphlet
deleted file mode 100644
index b1f1801..0000000
--- a/src/algebra/poltopol.spad.pamphlet
+++ /dev/null
@@ -1,204 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra poltopol.spad}
-\author{Manuel Bronstein, Patrizia Gianni}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package MPC2 MPolyCatFunctions2}
-<<package MPC2 MPolyCatFunctions2>>=
-)abbrev package MPC2 MPolyCatFunctions2
-++ Utilities for MPolyCat
-++ Author: Manuel Bronstein
-++ Date Created: 1987
-++ Date Last Updated: 28 March 1990  (PG)
-MPolyCatFunctions2(VarSet,E1,E2,R,S,PR,PS) : public == private where
- 
-  VarSet : OrderedSet
-  E1     : OrderedAbelianMonoidSup
-  E2     : OrderedAbelianMonoidSup
-  R      : Ring
-  S      : Ring
-  PR     : PolynomialCategory(R,E1,VarSet)
-  PS     : PolynomialCategory(S,E2,VarSet)
-  SUPR   ==> SparseUnivariatePolynomial PR
-  SUPS   ==> SparseUnivariatePolynomial PS
- 
-  public == with
-    map:     (R -> S,PR) -> PS
-	++ map(f,p) \undocumented	
-    reshape: (List S, PR) -> PS
-	++ reshape(l,p) \undocumented
- 
-  private == add
- 
-    supMap:  (R -> S, SUPR) -> SUPS
- 
-    supMap(fn : R -> S, supr : SUPR): SUPS ==
-      supr = 0 => monomial(fn(0$R) :: PS,0)$SUPS
-      c : PS := map(fn,leadingCoefficient supr)$%
-      monomial(c,degree supr)$SUPS + supMap(fn, reductum supr)
- 
-    map(fn : R -> S, pr : PR): PS ==
-      varu : Union(VarSet,"failed") := mainVariable pr
-      varu case "failed" =>  -- have a constant
-        fn(retract pr) :: PS
-      var : VarSet := varu :: VarSet
-      supr : SUPR := univariate(pr,var)$PR
-      multivariate(supMap(fn,supr),var)$PS
-
-@
-\section{package MPC3 MPolyCatFunctions3}
-<<package MPC3 MPolyCatFunctions3>>=
-)abbrev package MPC3 MPolyCatFunctions3
-++ Description:
-++ This package \undocumented
-MPolyCatFunctions3(Vars1,Vars2,E1,E2,R,PR1,PR2): C == T where
-  E1   : OrderedAbelianMonoidSup
-  E2   : OrderedAbelianMonoidSup
-  Vars1: OrderedSet
-  Vars2: OrderedSet
-  R    : Ring
-  PR1  : PolynomialCategory(R,E1,Vars1)
-  PR2  : PolynomialCategory(R,E2,Vars2)
- 
-  C ==> with
-    map: (Vars1 -> Vars2, PR1) -> PR2
-	++ map(f,x) \undocumented
- 
-  T ==> add
- 
-    map(f:Vars1 -> Vars2, p:PR1):PR2 ==
-      (x1 := mainVariable p) case "failed" =>
-        c:R:=(retract p)
-        c::PR2
-      up := univariate(p, x1::Vars1)
-      x2 := f(x1::Vars1)
-      ans:PR2 := 0
-      while up ^= 0 repeat
-        ans := ans + monomial(map(f,leadingCoefficient up),x2,degree up)
-        up  := reductum up
-      ans
-
-@
-\section{package POLTOPOL PolToPol}
-<<package POLTOPOL PolToPol>>=
-)abbrev package POLTOPOL PolToPol
-++ Author : P.Gianni, Summer '88
-++ Description:
-++ Package with the conversion functions among different kind of polynomials
-PolToPol(lv,R) : C == T
- 
- where
-  R      :    Ring
-  lv     :    List Symbol
-  NNI    ==>  NonNegativeInteger
-  Ov     ==>  OrderedVariableList(lv)
-  IES    ==>  IndexedExponents Symbol
- 
-  DP     ==>  DirectProduct(#lv,NonNegativeInteger)
-  DPoly  ==>  DistributedMultivariatePolynomial(lv,R)
- 
-  HDP    ==>  HomogeneousDirectProduct(#lv,NonNegativeInteger)
-  HDPoly ==>  HomogeneousDistributedMultivariatePolynomial(lv,R)
-  P      ==>  Polynomial R
-  VV     ==>  Vector NNI
-  MPC3   ==>  MPolyCatFunctions3
- 
-  C == with
-     dmpToHdmp    :    DPoly    -> HDPoly
-       ++ dmpToHdmp(p) converts p from a \spadtype{DMP} to a \spadtype{HDMP}.
-     hdmpToDmp    :   HDPoly    -> DPoly
-       ++ hdmpToDmp(p) converts p from a \spadtype{HDMP} to a \spadtype{DMP}.
-     pToHdmp      :     P       -> HDPoly
-       ++ pToHdmp(p) converts p from a \spadtype{POLY} to a \spadtype{HDMP}.
-     hdmpToP      :   HDPoly    -> P
-       ++ hdmpToP(p) converts p from a \spadtype{HDMP} to a \spadtype{POLY}.
-     dmpToP       :    DPoly    -> P
-       ++ dmpToP(p) converts p from a \spadtype{DMP} to a \spadtype{POLY}.
-     pToDmp       :     P       -> DPoly
-       ++ pToDmp(p) converts p from a \spadtype{POLY} to a \spadtype{DMP}.
-  T == add
- 
-    variable1(xx:Symbol):Ov == variable(xx)::Ov
- 
-   -- transform a P in a HDPoly --
-    pToHdmp(pol:P) : HDPoly ==
-      map(variable1,pol)$MPC3(Symbol,Ov,IES,HDP,R,P,HDPoly)
- 
-   -- transform an HDPoly in a P --
-    hdmpToP(hdpol:HDPoly) : P ==
-      map(convert,hdpol)$MPC3(Ov,Symbol,HDP,IES,R,HDPoly,P)
- 
-   -- transform an DPoly in a P --
-    dmpToP(dpol:DPoly) : P ==
-      map(convert,dpol)$MPC3(Ov,Symbol,DP,IES,R,DPoly,P)
- 
-   -- transform a P in a DPoly --
-    pToDmp(pol:P) : DPoly ==
-      map(variable1,pol)$MPC3(Symbol,Ov,IES,DP,R,P,DPoly)
- 
-   -- transform a DPoly in a HDPoly --
-    dmpToHdmp(dpol:DPoly) : HDPoly ==
-      dpol=0 => 0$HDPoly
-      monomial(leadingCoefficient dpol,
-               directProduct(degree(dpol)::VV)$HDP)$HDPoly+
-                                                 dmpToHdmp(reductum dpol)
- 
-   -- transform a HDPoly in a DPoly --
-    hdmpToDmp(hdpol:HDPoly) : DPoly ==
-      hdpol=0 => 0$DPoly
-      dd:DP:= directProduct((degree hdpol)::VV)$DP
-      monomial(leadingCoefficient hdpol,dd)$DPoly+
-               hdmpToDmp(reductum hdpol)
-
-@
-\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 MPC2 MPolyCatFunctions2>>
-<<package MPC3 MPolyCatFunctions3>>
-<<package POLTOPOL PolToPol>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/poly.spad.pamphlet b/src/algebra/poly.spad.pamphlet
deleted file mode 100644
index 1510a53..0000000
--- a/src/algebra/poly.spad.pamphlet
+++ /dev/null
@@ -1,486 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra poly.spad}
-\author{Dave Barton, James Davenport, Barry Trager, Patrizia Gianni, Marc Moreno Maza}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package SUP2 SparseUnivariatePolynomialFunctions2}
-<<package SUP2 SparseUnivariatePolynomialFunctions2>>=
-)abbrev package SUP2 SparseUnivariatePolynomialFunctions2
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package lifts a mapping from coefficient rings R to S to
-++ a mapping from sparse univariate polynomial over R to
-++ a sparse univariate polynomial over S.
-++ Note that the mapping is assumed
-++ to send zero to zero, since it will only be applied to the non-zero
-++ coefficients of the polynomial.
-
-SparseUnivariatePolynomialFunctions2(R:Ring, S:Ring): with
-  map:(R->S,SparseUnivariatePolynomial R) -> SparseUnivariatePolynomial S
-    ++ map(func, poly) creates a new polynomial by applying func to
-    ++ every non-zero coefficient of the polynomial poly.
- == add
-  map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
-           SparseUnivariatePolynomial R, S, SparseUnivariatePolynomial S)
-
-@
-\section{package UP2 UnivariatePolynomialFunctions2}
-<<package UP2 UnivariatePolynomialFunctions2>>=
-)abbrev package UP2 UnivariatePolynomialFunctions2
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package lifts a mapping from coefficient rings R to S to
-++ a mapping from \spadtype{UnivariatePolynomial}(x,R) to
-++ \spadtype{UnivariatePolynomial}(y,S). Note that the mapping is assumed
-++ to send zero to zero, since it will only be applied to the non-zero
-++ coefficients of the polynomial.
-
-UnivariatePolynomialFunctions2(x:Symbol, R:Ring, y:Symbol, S:Ring): with
-  map: (R -> S, UnivariatePolynomial(x,R)) -> UnivariatePolynomial(y,S)
-    ++ map(func, poly) creates a new polynomial by applying func to
-    ++ every non-zero coefficient of the polynomial poly.
- == add
-  map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
-              UnivariatePolynomial(x, R), S, UnivariatePolynomial(y, S))
-
-@
-\section{package POLY2UP PolynomialToUnivariatePolynomial}
-<<package POLY2UP PolynomialToUnivariatePolynomial>>=
-)abbrev package POLY2UP PolynomialToUnivariatePolynomial
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package is primarily to help the interpreter do coercions.
-++ It allows you to view a polynomial as a
-++ univariate polynomial in one of its variables with
-++ coefficients which are again a polynomial in all the
-++ other variables.
-
-PolynomialToUnivariatePolynomial(x:Symbol, R:Ring): with
-  univariate: (Polynomial R, Variable x) ->
-                                   UnivariatePolynomial(x, Polynomial R)
-     ++ univariate(p, x) converts the polynomial p to a one of type
-     ++ \spad{UnivariatePolynomial(x,Polynomial(R))}, ie. as a member of \spad{R[...][x]}.
- == add
-  univariate(p, y) ==
-    q:SparseUnivariatePolynomial(Polynomial R) := univariate(p, x)
-    map(#1, q)$UnivariatePolynomialCategoryFunctions2(Polynomial R,
-                  SparseUnivariatePolynomial Polynomial R, Polynomial R,
-                      UnivariatePolynomial(x, Polynomial R))
-
-@
-\section{package UPSQFREE UnivariatePolynomialSquareFree}
-<<package UPSQFREE UnivariatePolynomialSquareFree>>=
-)abbrev package UPSQFREE UnivariatePolynomialSquareFree
-++ Author: Dave Barton, Barry Trager
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions: squareFree, squareFreePart
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package provides for square-free decomposition of
-++ univariate polynomials over arbitrary rings, i.e.
-++ a partial factorization such that each factor is a product
-++ of irreducibles with multiplicity one and the factors are
-++ pairwise relatively prime. If the ring
-++ has characteristic zero, the result is guaranteed to satisfy
-++ this condition. If the ring is an infinite ring of
-++ finite characteristic, then it may not be possible to decide when
-++ polynomials contain factors which are pth powers. In this
-++ case, the flag associated with that polynomial is set to "nil"
-++ (meaning that that polynomials are not guaranteed to be square-free).
-
-UnivariatePolynomialSquareFree(RC:IntegralDomain,P):C == T
-  where
-    fUnion ==> Union("nil", "sqfr", "irred", "prime")
-    FF     ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
-    P:Join(UnivariatePolynomialCategory(RC),IntegralDomain) with
-      gcd: (%,%) -> %
-        ++ gcd(p,q) computes the greatest-common-divisor of p and q.
-
-    C == with
-      squareFree: P -> Factored(P)
-        ++ squareFree(p) computes the square-free factorization of the
-        ++ univariate polynomial p. Each factor has no repeated roots, and the
-        ++ factors are pairwise relatively prime.
-      squareFreePart: P -> P
-        ++ squareFreePart(p) returns a polynomial which has the same
-        ++ irreducible factors as the univariate polynomial p, but each
-        ++ factor has multiplicity one.
-      BumInSepFFE: FF -> FF
-        ++ BumInSepFFE(f) is a local function, exported only because
-        ++ it has multiple conditional definitions.
-
-    T == add
-
-      if RC has CharacteristicZero then
-        squareFreePart(p:P) == (p exquo gcd(p, differentiate p))::P
-      else
-        squareFreePart(p:P) ==
-          unit(s := squareFree(p)$%) * */[f.factor for f in factors s]
-
-      if RC has FiniteFieldCategory then
-        BumInSepFFE(ffe:FF) ==
-           ["sqfr", map(charthRoot,ffe.fctr), characteristic$P*ffe.xpnt]
-      else if RC has CharacteristicNonZero then
-         BumInSepFFE(ffe:FF) ==
-            np := multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger)
-            (nthrp := charthRoot(np)) case "failed" =>
-               ["nil", np, ffe.xpnt]
-            ["sqfr", nthrp, characteristic$P*ffe.xpnt]
-
-      else
-        BumInSepFFE(ffe:FF) ==
-          ["nil",
-           multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger),
-            ffe.xpnt]
-
-
-      if RC has CharacteristicZero then
-        squareFree(p:P) ==             --Yun's algorithm - see SYMSAC '76, p.27
-           --Note ci primitive is, so GCD's don't need to %do contents.
-           --Change gcd to return cofctrs also?
-           ci:=p; di:=differentiate(p); pi:=gcd(ci,di)
-           degree(pi)=0 =>
-             (u,c,a):=unitNormal(p)
-             makeFR(u,[["sqfr",c,1]])
-           i:NonNegativeInteger:=0; lffe:List FF:=[]
-           lcp := leadingCoefficient p
-           while degree(ci)^=0 repeat
-              ci:=(ci exquo pi)::P
-              di:=(di exquo pi)::P - differentiate(ci)
-              pi:=gcd(ci,di)
-              i:=i+1
-              degree(pi) > 0 =>
-                 lcp:=(lcp exquo (leadingCoefficient(pi)**i))::RC
-                 lffe:=[["sqfr",pi,i],:lffe]
-           makeFR(lcp::P,lffe)
-
-      else
-        squareFree(p:P) ==           --Musser's algorithm - see SYMSAC '76, p.27
-             --p MUST BE PRIMITIVE, Any characteristic.
-             --Note ci primitive, so GCD's don't need to %do contents.
-             --Change gcd to return cofctrs also?
-           ci := gcd(p,differentiate(p))
-           degree(ci)=0 =>
-             (u,c,a):=unitNormal(p)
-             makeFR(u,[["sqfr",c,1]])
-           di := (p exquo ci)::P
-           i:NonNegativeInteger:=0; lffe:List FF:=[]
-           dunit : P := 1
-           while degree(di)^=0 repeat
-              diprev := di
-              di := gcd(ci,di)
-              ci:=(ci exquo di)::P
-              i:=i+1
-              degree(diprev) = degree(di) =>
-                 lc := (leadingCoefficient(diprev) exquo leadingCoefficient(di))::RC
-                 dunit := lc**i * dunit
-              pi:=(diprev exquo di)::P
-              lffe:=[["sqfr",pi,i],:lffe]
-           dunit := dunit * di ** (i+1)
-           degree(ci)=0 => makeFR(dunit*ci,lffe)
-           redSqfr:=squareFree(divideExponents(ci,characteristic$P)::P)
-           lsnil:= [BumInSepFFE(ffe) for ffe in factorList redSqfr]
-           lffe:=append(lsnil,lffe)
-           makeFR(dunit*(unit redSqfr),lffe)
-
-@
-\section{package PSQFR PolynomialSquareFree}
-<<package PSQFR PolynomialSquareFree>>=
-)abbrev package PSQFR PolynomialSquareFree
-++ Author:
-++ Date Created:
-++ Date Last Updated: November 1993, (P.Gianni)
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package computes square-free decomposition of multivariate
-++ polynomials over a coefficient ring which is an arbitrary gcd domain.
-++ The requirement on the coefficient domain guarantees that the \spadfun{content} can be
-++ removed so that factors will be primitive as well as square-free.
-++ Over an infinite ring of finite characteristic,it may not be possible to
-++ guarantee that the factors are square-free.
-
-PolynomialSquareFree(VarSet:OrderedSet,E,RC:GcdDomain,P):C == T where
-  E:OrderedAbelianMonoidSup
-  P:PolynomialCategory(RC,E,VarSet)
-
-  C == with
-    squareFree : P -> Factored P
-      ++ squareFree(p) returns the square-free factorization of the
-      ++ polynomial p.  Each factor has no repeated roots, and the
-      ++ factors are pairwise relatively prime.
-
-  T == add
-    SUP    ==> SparseUnivariatePolynomial(P)
-    NNI    ==> NonNegativeInteger
-    fUnion ==> Union("nil", "sqfr", "irred", "prime")
-    FF     ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
-
-    finSqFr : (P,List VarSet) -> Factored P
-    pthPower : P -> Factored P
-    pPolRoot : P -> P
-    putPth   : P -> P
-
-    chrc:=characteristic$RC
-
-    if RC has CharacteristicNonZero then
-    -- find the p-th root of a polynomial
-      pPolRoot(f:P) : P ==
-        lvar:=variables f
-        empty? lvar => f
-        mv:=first lvar
-        uf:=univariate(f,mv)
-        uf:=divideExponents(uf,chrc)::SUP
-        uf:=map(pPolRoot,uf)
-        multivariate(uf,mv)
-
-    -- substitute variables with their p-th power
-      putPth(f:P) : P ==
-        lvar:=variables f
-        empty? lvar => f
-        mv:=first lvar
-        uf:=univariate(f,mv)
-        uf:=multiplyExponents(uf,chrc)::SUP
-        uf:=map(putPth,uf)
-        multivariate(uf,mv)
-
-    -- the polynomial is a perfect power
-      pthPower(f:P) : Factored P ==
-        proot : P := 0
-        isSq  : Boolean := false
-        if (g:=charthRoot f) case "failed" then proot:=pPolRoot(f)
-        else
-          proot := g :: P
-          isSq  := true
-        psqfr:=finSqFr(proot,variables f)
-        isSq  =>
-          makeFR((unit psqfr)**chrc,[[u.flg,u.fctr,
-           (u.xpnt)*chrc] for u in factorList psqfr])
-        makeFR((unit psqfr),[["nil",putPth u.fctr,u.xpnt]
-                             for u in factorList psqfr])
-
-    -- compute the square free decomposition, finite characteristic case
-      finSqFr(f:P,lvar:List VarSet) : Factored P ==
-         empty? lvar => pthPower(f)
-         mv:=first lvar
-         lvar:=lvar.rest
-         differentiate(f,mv)=0 => finSqFr(f,lvar)
-         uf:=univariate(f,mv)
-         cont := content uf
-         cont1:P:=1
-         uf := (uf exquo cont)::SUP
-         squf := squareFree(uf)$UnivariatePolynomialSquareFree(P,SUP)
-         pfaclist:List FF :=[]
-         for u in factorList squf repeat
-           uexp:NNI:=(u.xpnt):NNI
-           u.flg = "sqfr" =>  -- the square free factor is OK
-             pfaclist:= cons([u.flg,multivariate(u.fctr,mv),uexp],
-                              pfaclist)
-           --listfin1:= finSqFr(multivariate(u.fctr,mv),lvar)
-           listfin1:= squareFree multivariate(u.fctr,mv)
-           flistfin1:=[[uu.flg,uu.fctr,uu.xpnt*uexp]
-                        for uu in factorList listfin1]
-           cont1:=cont1*((unit listfin1)**uexp)
-           pfaclist:=append(flistfin1,pfaclist)
-         cont:=cont*cont1
-         cont ^= 1 =>
-           sqp := squareFree cont
-           pfaclist:= append (factorList sqp,pfaclist)
-           makeFR(unit(sqp)*coefficient(unit squf,0),pfaclist)
-         makeFR(coefficient(unit squf,0),pfaclist)
-
-    squareFree(p:P) ==
-       mv:=mainVariable p
-       mv case "failed" => makeFR(p,[])$Factored(P)
-       characteristic$RC ^=0 => finSqFr(p,variables p)
-       up:=univariate(p,mv)
-       cont := content up
-       up := (up exquo cont)::SUP
-       squp := squareFree(up)$UnivariatePolynomialSquareFree(P,SUP)
-       pfaclist:List FF :=
-         [[u.flg,multivariate(u.fctr,mv),u.xpnt]
-                                            for u in factorList squp]
-       cont ^= 1 =>
-         sqp := squareFree cont
-         makeFR(unit(sqp)*coefficient(unit squp,0),
-              append(factorList sqp, pfaclist))
-       makeFR(coefficient(unit squp,0),pfaclist)
-
-@
-\section{package UPMP UnivariatePolynomialMultiplicationPackage}
-<<package UPMP UnivariatePolynomialMultiplicationPackage>>=
-)abbrev package UPMP UnivariatePolynomialMultiplicationPackage
-++ Author: Marc Moreno Maza
-++ Date Created: 14.08.2000
-++ Description:
-++ This package implements Karatsuba's trick for multiplying
-++ (large) univariate polynomials. It could be improved with
-++ a version doing the work on place and also with a special
-++ case for squares. We've done this in Basicmath, but we
-++ believe that this out of the scope of AXIOM.
-
-UnivariatePolynomialMultiplicationPackage(R: Ring, U: UnivariatePolynomialCategory(R)): C == T
-  where
-    HL ==> Record(quotient:U,remainder:U)
-    C == with
-      noKaratsuba: (U, U) -> U
-        ++ \spad{noKaratsuba(a,b)} returns \spad{a*b} without
-        ++ using Karatsuba's trick at all.
-      karatsubaOnce: (U, U) -> U
-        ++ \spad{karatsuba(a,b)} returns \spad{a*b} by applying
-        ++ Karatsuba's trick once. The other multiplications
-        ++ are performed by calling \spad{*} from \spad{U}.
-      karatsuba: (U, U, NonNegativeInteger, NonNegativeInteger) -> U;
-        ++ \spad{karatsuba(a,b,l,k)} returns \spad{a*b} by applying
-        ++ Karatsuba's trick provided that both \spad{a} and \spad{b}
-        ++ have at least \spad{l} terms and \spad{k > 0} holds
-        ++ and by calling \spad{noKaratsuba} otherwise. The other
-        ++ multiplications are performed by recursive calls with
-        ++ the same third argument and \spad{k-1} as fourth argument.
-
-    T == add
-      noKaratsuba(a,b) ==
-        zero? a => a
-        zero? b => b
-        zero?(degree(a)) => leadingCoefficient(a) * b
-        zero?(degree(b)) => a * leadingCoefficient(b)
-        lu: List(U) := reverse monomials(a)
-        res: U := 0;
-        for u in lu repeat
-          res := pomopo!(res, leadingCoefficient(u), degree(u), b)
-        res
-      karatsubaOnce(a:U,b:U): U ==
-        da := minimumDegree(a)
-        db := minimumDegree(b)
-        if not zero? da then a := shiftRight(a,da)
-        if not zero? db then b := shiftRight(b,db)
-        d := da + db
-        n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
-        rec: HL := karatsubaDivide(a, n)
-        ha := rec.quotient
-        la := rec.remainder
-        rec := karatsubaDivide(b, n)
-        hb := rec.quotient
-        lb := rec.remainder
-        w: U := (ha - la) * (lb - hb)
-        u: U := la * lb
-        v: U := ha * hb
-        w := w + (u + v)
-        w := shiftLeft(w,n) + u
-        zero? d => shiftLeft(v,2*n) + w
-        shiftLeft(v,2*n + d) + shiftLeft(w,d)
-      karatsuba(a:U,b:U,l:NonNegativeInteger,k:NonNegativeInteger): U ==
-        zero? k => noKaratsuba(a,b)
-        degree(a) < l => noKaratsuba(a,b)
-        degree(b) < l => noKaratsuba(a,b)
-        numberOfMonomials(a) < l => noKaratsuba(a,b)
-        numberOfMonomials(b) < l => noKaratsuba(a,b)
-        da := minimumDegree(a)
-        db := minimumDegree(b)
-        if not zero? da then a := shiftRight(a,da)
-        if not zero? db then b := shiftRight(b,db)
-        d := da + db
-        n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
-        k := subtractIfCan(k,1)::NonNegativeInteger
-        rec: HL := karatsubaDivide(a, n)
-        ha := rec.quotient
-        la := rec.remainder
-        rec := karatsubaDivide(b, n)
-        hb := rec.quotient
-        lb := rec.remainder
-        w: U := karatsuba(ha - la, lb - hb, l, k)
-        u: U := karatsuba(la, lb, l, k)
-        v: U := karatsuba(ha, hb, l, k)
-        w := w + (u + v)
-        w := shiftLeft(w,n) + u
-        zero? d => shiftLeft(v,2*n) + w
-        shiftLeft(v,2*n + d) + shiftLeft(w,d)
-
-@
-\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 UPSQFREE UnivariatePolynomialSquareFree>>
-<<package PSQFR PolynomialSquareFree>>
-<<package UPMP UnivariatePolynomialMultiplicationPackage>>
-<<package SUP2 SparseUnivariatePolynomialFunctions2>>
-<<package UP2 UnivariatePolynomialFunctions2>>
-<<package POLY2UP PolynomialToUnivariatePolynomial>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/polycat.spad.pamphlet b/src/algebra/polycat.spad.pamphlet
deleted file mode 100644
index 39b0d38..0000000
--- a/src/algebra/polycat.spad.pamphlet
+++ /dev/null
@@ -1,194 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra polycat.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package POLYLIFT PolynomialCategoryLifting}
-<<dot>>=
-"POLYLIFT" -> "PACKAGE"
-"PolynomialCategoryLifting(a:OAMONS,b:ORDSET,c:RING,d:POLYCAT(c,a,b),e:SETCAT)"
-    -> "Package"
-@
-<<package POLYLIFT PolynomialCategoryLifting>>=
-)abbrev package POLYLIFT PolynomialCategoryLifting
-++ Author: Manuel Bronstein
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ This package provides a very general map function, which
-++ given a set S and polynomials over R with maps from the
-++ variables into S and the coefficients into S, maps polynomials
-++ into S. S is assumed to support \spad{+}, \spad{*} and \spad{**}.
-
-PolynomialCategoryLifting(E,Vars,R,P,S): Exports == Implementation where
-  E   : OrderedAbelianMonoidSup
-  Vars: OrderedSet
-  R   : Ring
-  P   : PolynomialCategory(R, E, Vars)
-  S   : SetCategory with
-           "+" : (%, %) -> %
-           "*" : (%, %) -> %
-           "**": (%, NonNegativeInteger) -> %
-
-  Exports ==> with
-    map: (Vars -> S, R -> S, P) -> S
-      ++ map(varmap, coefmap, p) takes a
-      ++ varmap, a mapping from the variables of polynomial p into S,
-      ++ coefmap, a mapping from coefficients of p into S, and p, and
-      ++ produces a member of S using the corresponding arithmetic.
-      ++ in S
-
-  Implementation ==> add
-    map(fv, fc, p) ==
-      (x1 := mainVariable p) case "failed" => fc leadingCoefficient p
-      up := univariate(p, x1::Vars)
-      t  := fv(x1::Vars)
-      ans:= fc 0
-      while not ground? up repeat
-        ans := ans + map(fv,fc, leadingCoefficient up) * t ** (degree up)
-        up  := reductum up
-      ans + map(fv, fc, leadingCoefficient up)
-
-@
-\section{package UPOLYC2 UnivariatePolynomialCategoryFunctions2}
-<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>=
-)abbrev package UPOLYC2 UnivariatePolynomialCategoryFunctions2
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ Mapping from polynomials over R to polynomials over S
-++ given a map from R to S assumed to send zero to zero.
-
-UnivariatePolynomialCategoryFunctions2(R,PR,S,PS): Exports == Impl where
-  R, S: Ring
-  PR  : UnivariatePolynomialCategory R
-  PS  : UnivariatePolynomialCategory S
-
-  Exports ==> with
-    map: (R -> S, PR) -> PS
-     ++ map(f, p) takes a function f from R to S,
-     ++ and applies it to each (non-zero) coefficient of a polynomial p
-     ++ over R, getting a new polynomial over S.
-     ++ Note: since the map is not applied to zero elements, it may map zero
-     ++ to zero.
-
-  Impl ==> add
-    map(f, p) ==
-      ans:PS := 0
-      while p ^= 0 repeat
-        ans := ans + monomial(f leadingCoefficient p, degree p)
-        p   := reductum p
-      ans
-
-@
-\section{package COMMUPC CommuteUnivariatePolynomialCategory}
-<<package COMMUPC CommuteUnivariatePolynomialCategory>>=
-)abbrev package COMMUPC CommuteUnivariatePolynomialCategory
-++ Author: Manuel Bronstein
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ A package for swapping the order of two variables in a tower of two
-++ UnivariatePolynomialCategory extensions.
-
-CommuteUnivariatePolynomialCategory(R, UP, UPUP): Exports == Impl where
-  R   : Ring
-  UP  : UnivariatePolynomialCategory R
-  UPUP: UnivariatePolynomialCategory UP
-
-  N ==> NonNegativeInteger
-
-  Exports ==> with
-    swap: UPUP -> UPUP
-      ++ swap(p(x,y)) returns p(y,x).
-
-  Impl ==> add
-    makePoly: (UP, N) -> UPUP
-
--- converts P(x,y) to P(y,x)
-    swap poly ==
-      ans:UPUP := 0
-      while poly ^= 0 repeat
-        ans  := ans + makePoly(leadingCoefficient poly, degree poly)
-        poly := reductum poly
-      ans
-
-    makePoly(poly, d) ==
-      ans:UPUP := 0
-      while poly ^= 0 repeat
-        ans  := ans +
-             monomial(monomial(leadingCoefficient poly, d), degree poly)
-        poly := reductum poly
-      ans
-
-@
-\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 POLYLIFT PolynomialCategoryLifting>>
-<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>
-<<package COMMUPC CommuteUnivariatePolynomialCategory>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/primelt.spad.pamphlet b/src/algebra/primelt.spad.pamphlet
deleted file mode 100644
index baee4e6..0000000
--- a/src/algebra/primelt.spad.pamphlet
+++ /dev/null
@@ -1,269 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra primelt.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PRIMELT PrimitiveElement}
-<<package PRIMELT PrimitiveElement>>=
-)abbrev package PRIMELT PrimitiveElement
-++ Computation of primitive elements.
-++ Author: Manuel Bronstein
-++ Date Created: 6 Jun 1990
-++ Date Last Updated: 25 April 1991
-++ Description:
-++   PrimitiveElement provides functions to compute primitive elements
-++   in algebraic extensions;
-++ Keywords: algebraic, extension, primitive.
-PrimitiveElement(F): Exports == Implementation where
-  F : Join(Field, CharacteristicZero)
-
-  SY  ==> Symbol
-  P   ==> Polynomial F
-  UP  ==> SparseUnivariatePolynomial F
-  RC  ==> Record(coef1: Integer, coef2: Integer, prim:UP)
-  REC ==> Record(coef: List Integer, poly:List UP, prim: UP)
-
-  Exports ==> with
-    primitiveElement: (P, SY, P, SY) -> RC
-      ++ primitiveElement(p1, a1, p2, a2) returns \spad{[c1, c2, q]}
-      ++ such that \spad{k(a1, a2) = k(a)}
-      ++ where \spad{a = c1 a1 + c2 a2, and q(a) = 0}.
-      ++ The pi's are the defining polynomials for the ai's.
-      ++ The p2 may involve a1, but p1 must not involve a2.
-      ++ This operation uses \spadfun{resultant}.
-    primitiveElement: (List P, List SY) -> REC
-      ++ primitiveElement([p1,...,pn], [a1,...,an]) returns
-      ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
-      ++ such that then \spad{k(a1,...,an) = k(a)},
-      ++ where \spad{a = a1 c1 + ... + an cn},
-      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
-      ++ The pi's are the defining polynomials for the ai's.
-      ++ This operation uses the technique of
-      ++ \spadglossSee{groebner bases}{Groebner basis}.
-    primitiveElement: (List P, List SY, SY) -> REC
-      ++ primitiveElement([p1,...,pn], [a1,...,an], a) returns
-      ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
-      ++ such that then \spad{k(a1,...,an) = k(a)},
-      ++ where \spad{a = a1 c1 + ... + an cn},
-      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
-      ++ The pi's are the defining polynomials for the ai's.
-      ++ This operation uses the technique of
-      ++ \spadglossSee{groebner bases}{Groebner basis}.
-
-  Implementation ==> add
-    import PolyGroebner(F)
-
-    multi     : (UP, SY) -> P
-    randomInts: (NonNegativeInteger, NonNegativeInteger) -> List Integer
-    findUniv  : (List P, SY, SY) -> Union(P, "failed")
-    incl?     : (List SY, List SY) -> Boolean
-    triangularLinearIfCan:(List P,List SY,SY) -> Union(List UP,"failed")
-    innerPrimitiveElement: (List P, List SY, SY) -> REC
-
-    multi(p, v)            == multivariate(map(#1, p), v)
-    randomInts(n, m)       == [symmetricRemainder(random()$Integer, m) for i in 1..n]
-    incl?(a, b)            == every?(member?(#1, b), a)
-    primitiveElement(l, v) == primitiveElement(l, v, new()$SY)
-
-    primitiveElement(p1, a1, p2, a2) ==
---      one? degree(p2, a1) => [0, 1, univariate resultant(p1, p2, a1)]
-      (degree(p2, a1) = 1) => [0, 1, univariate resultant(p1, p2, a1)]
-      u := (new()$SY)::P
-      b := a2::P
-      for i in 10.. repeat
-        c := symmetricRemainder(random()$Integer, i)
-        w := u - c * b
-        r := univariate resultant(eval(p1, a1, w), eval(p2, a1, w), a2)
-        not zero? r and r = squareFreePart r => return [1, c, r]
-
-    findUniv(l, v, opt) ==
-      for p in l repeat
-        degree(p, v) > 0 and incl?(variables p, [v, opt]) => return p
-      "failed"
-
-    triangularLinearIfCan(l, lv, w) ==
-      (u := findUniv(l, w, w)) case "failed" => "failed"
-      pw := univariate(u::P)
-      ll := nil()$List(UP)
-      for v in lv repeat
-        ((u := findUniv(l, v, w)) case "failed") or
-          (degree(p := univariate(u::P, v)) ^= 1) => return "failed"
-        (bc := extendedEuclidean(univariate leadingCoefficient p, pw,1))
-           case "failed" => error "Should not happen"
-        ll := concat(map(#1,
-                (- univariate(coefficient(p,0)) * bc.coef1) rem pw), ll)
-      concat(map(#1, pw), reverse_! ll)
-
-    primitiveElement(l, vars, uu) ==
-      u    := uu::P
-      vv   := [v::P for v in vars]
-      elim := concat(vars, uu)
-      w    := uu::P
-      n    := #l
-      for i in 10.. repeat
-        cf := randomInts(n, i)
-        (tt := triangularLinearIfCan(lexGroebner(
-             concat(w - +/[c * t for c in cf for t in vv], l), elim),
-                vars, uu)) case List(UP) =>
-                   ltt := tt::List(UP)
-                   return([cf, rest ltt, first ltt])
-
-@
-\section{package FSPRMELT FunctionSpacePrimitiveElement}
-<<package FSPRMELT FunctionSpacePrimitiveElement>>=
-)abbrev package FSPRMELT FunctionSpacePrimitiveElement
-++ Computation of primitive elements.
-++ Author: Manuel Bronstein
-++ Date Created: 6 Jun 1990
-++ Date Last Updated: 25 April 1991
-++ Description:
-++   FunctionsSpacePrimitiveElement provides functions to compute
-++   primitive elements in functions spaces;
-++ Keywords: algebraic, extension, primitive.
-FunctionSpacePrimitiveElement(R, F): Exports == Implementation where
-  R: Join(IntegralDomain, OrderedSet, CharacteristicZero)
-  F: FunctionSpace R
-
-  SY  ==> Symbol
-  P   ==> Polynomial F
-  K   ==> Kernel F
-  UP  ==> SparseUnivariatePolynomial F
-  REC ==> Record(primelt:F, poly:List UP, prim:UP)
-
-  Exports ==> with
-    primitiveElement: List F -> Record(primelt:F, poly:List UP, prim:UP)
-      ++ primitiveElement([a1,...,an]) returns \spad{[a, [q1,...,qn], q]}
-      ++ such that then \spad{k(a1,...,an) = k(a)},
-      ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
-      ++ This operation uses the technique of
-      ++ \spadglossSee{groebner bases}{Groebner basis}.
-    if F has AlgebraicallyClosedField then
-      primitiveElement: (F,F)->Record(primelt:F,pol1:UP,pol2:UP,prim:UP)
-        ++ primitiveElement(a1, a2) returns \spad{[a, q1, q2, q]}
-        ++ such that \spad{k(a1, a2) = k(a)},
-        ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
-        ++ The minimal polynomial for a2 may involve a1, but the
-        ++ minimal polynomial for a1 may not involve a2;
-        ++ This operations uses \spadfun{resultant}.
-
-  Implementation ==> add
-    import PrimitiveElement(F)
-    import AlgebraicManipulations(R, F)
-    import PolynomialCategoryLifting(IndexedExponents K,
-                            K, R, SparseMultivariatePolynomial(R, K), P)
-
-    F2P: (F, List SY) -> P
-    K2P: (K, List SY) -> P
-
-    F2P(f, l) == inv(denom(f)::F) * map(K2P(#1, l), #1::F::P, numer f)
-
-    K2P(k, l) ==
-      ((v := symbolIfCan k) case SY) and member?(v::SY, l) => v::SY::P
-      k::F::P
-
-    primitiveElement l ==
-      u    := string(uu := new()$SY)
-      vars := [concat(u, string i)::SY for i in 1..#l]
-      vv   := [kernel(v)$K :: F for v in vars]
-      kers := [retract(a)@K for a in l]
-      pols := [F2P(subst(ratDenom((minPoly k) v, kers), kers, vv), vars)
-                                              for k in kers for v in vv]
-      rec := primitiveElement(pols, vars, uu)
-      [+/[c * a for c in rec.coef for a in l], rec.poly, rec.prim]
-
-    if F has AlgebraicallyClosedField then
-      import PolynomialCategoryQuotientFunctions(IndexedExponents K,
-                            K, R, SparseMultivariatePolynomial(R, K), F)
-
-      F2UP: (UP, K, UP) -> UP
-      getpoly: (UP, F) -> UP
-
-      F2UP(p, k, q) ==
-        ans:UP := 0
-        while not zero? p repeat
-          f   := univariate(leadingCoefficient p, k)
-          ans := ans + ((numer f) q)
-                       * monomial(inv(retract(denom f)@F), degree p)
-          p   := reductum p
-        ans
-
-      primitiveElement(a1, a2) ==
-        a   := (aa := new()$SY)::F
-        b   := (bb := new()$SY)::F
-        l   := [aa, bb]$List(SY)
-        p1  := minPoly(k1 := retract(a1)@K)
-        p2  := map(subst(ratDenom(#1, [k1]), [k1], [a]),
-                                                 minPoly(retract(a2)@K))
-        rec := primitiveElement(F2P(p1 a, l), aa, F2P(p2 b, l), bb)
-        w   := rec.coef1 * a1 + rec.coef2 * a2
-        g   := rootOf(rec.prim)
-        zero?(rec.coef1) =>
-          c2g := inv(rec.coef2 :: F) * g
-          r := gcd(p1, univariate(p2 c2g, retract(a)@K, p1))
-          q := getpoly(r, g)
-          [w, q, rec.coef2 * monomial(1, 1)$UP, rec.prim]
-        ic1 := inv(rec.coef1 :: F)
-        gg  := (ic1 * g)::UP - monomial(rec.coef2 * ic1, 1)$UP
-        kg  := retract(g)@K
-        r   := gcd(p1 gg, F2UP(p2, retract(a)@K, gg))
-        q   := getpoly(r, g)
-        [w, monomial(ic1, 1)$UP - rec.coef2 * ic1 * q, q, rec.prim]
-
-      getpoly(r, g) ==
---        one? degree r =>
-        (degree r = 1) =>
-          k := retract(g)@K
-          univariate(-coefficient(r,0)/leadingCoefficient r,k,minPoly k)
-        error "GCD not of degree 1"
-
-@
-\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 PRIMELT PrimitiveElement>>
-<<package FSPRMELT FunctionSpacePrimitiveElement>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/print.spad.pamphlet b/src/algebra/print.spad.pamphlet
deleted file mode 100644
index 8d83639..0000000
--- a/src/algebra/print.spad.pamphlet
+++ /dev/null
@@ -1,75 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra print.spad}
-\author{Scott Morrison}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PRINT PrintPackage}
-<<package PRINT PrintPackage>>=
-)abbrev package PRINT PrintPackage
-++ Author: Scott Morrison
-++ Date Created: Aug. 1, 1990
-++ Date Last Updated: 
-++ Basic Operations: print
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: print
-++ References:
-++ Description: PrintPackage provides a print function for output forms.
-PrintPackage(): with
-    print : OutputForm ->  Void
-      ++ print(o) writes the output form o on standard output using the
-      ++ two-dimensional formatter.
- == add
-    print(x) == print(x)$OutputForm
-
-@
-\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 PRINT PrintPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/prs.spad.pamphlet b/src/algebra/prs.spad.pamphlet
deleted file mode 100644
index f366206..0000000
--- a/src/algebra/prs.spad.pamphlet
+++ /dev/null
@@ -1,986 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra prs.spad}
-\author{Lionel Ducos}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PRS PseudoRemainderSequence}
-The package constructor {\bf PseudoRemainderSequence} provides
-efficient algorithms by Lionel Ducos (University of Poitiers, France)
-for computing sub-resultants. This leads to a speed up in many places
-in Axiom where sub-resultants are computed (polynomial system solving,
-algebraic factorization, integration).
-<<package PRS PseudoRemainderSequence>>=
-)abbrev package PRS PseudoRemainderSequence
-++ Author: Ducos Lionel
-++ Date Created: january 1995
-++ Date Last Updated: 5 february 1999
-++ Basic Functions: 
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ Description: This package contains some functions:
-++ \axiomOpFrom{discriminant}{PseudoRemainderSequence}, 
-++ \axiomOpFrom{resultant}{PseudoRemainderSequence}, 
-++ \axiomOpFrom{subResultantGcd}{PseudoRemainderSequence},
-++ \axiomOpFrom{chainSubResultants}{PseudoRemainderSequence}, 
-++ \axiomOpFrom{degreeSubResultant}{PseudoRemainderSequence}, 
-++ \axiomOpFrom{lastSubResultant}{PseudoRemainderSequence},
-++ \axiomOpFrom{resultantEuclidean}{PseudoRemainderSequence}, 
-++ \axiomOpFrom{subResultantGcdEuclidean}{PseudoRemainderSequence},
-++ \axiomOpFrom{semiSubResultantGcdEuclidean1}{PseudoRemainderSequence},
-++ \axiomOpFrom{semiSubResultantGcdEuclidean2}{PseudoRemainderSequence}, etc.
-++ This procedures are coming from improvements 
-++ of the subresultants algorithm.
-++   Version : 7
-++   References : Lionel Ducos "Optimizations of the subresultant algorithm"
-++   to appear in the Journal of Pure and Applied Algebra.
-++   Author : Ducos Lionel \axiom{Lionel.Ducos@mathlabo.univ-poitiers.fr}
-
-PseudoRemainderSequence(R, polR) : Specification == Implementation where
-  R : IntegralDomain
-  polR : UnivariatePolynomialCategory(R)
-  NNI ==> NonNegativeInteger
-  LC  ==> leadingCoefficient
-
-  Specification == with
-       resultant : (polR, polR) -> R
-         ++ \axiom{resultant(P, Q)} returns the resultant 
-         ++ of \axiom{P} and \axiom{Q}
-
-       resultantEuclidean : (polR, polR) -> 
-                          Record(coef1 : polR, coef2 : polR, resultant : R)
-         ++ \axiom{resultantEuclidean(P,Q)} carries out the equality
-         ++ \axiom{coef1*P + coef2*Q = resultant(P,Q)}
-
-       semiResultantEuclidean2 : (polR, polR) -> 
-                          Record(coef2 : polR, resultant : R)
-         ++ \axiom{semiResultantEuclidean2(P,Q)} carries out the equality
-         ++ \axiom{...P + coef2*Q = resultant(P,Q)}.
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       semiResultantEuclidean1 : (polR, polR) -> 
-                          Record(coef1 : polR, resultant : R)
-         ++ \axiom{semiResultantEuclidean1(P,Q)} carries out the equality
-         ++ \axiom{coef1.P + ? Q = resultant(P,Q)}.
-
-       indiceSubResultant : (polR, polR, NNI) -> polR
-         ++ \axiom{indiceSubResultant(P, Q, i)} returns
-         ++ the subresultant of indice \axiom{i}
-
-       indiceSubResultantEuclidean : (polR, polR, NNI) -> 
-                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
-         ++ \axiom{indiceSubResultant(P, Q, i)} returns
-         ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
-         ++ \axiom{coef1*P + coef2*Q = S_i(P,Q)}
-
-       semiIndiceSubResultantEuclidean : (polR, polR, NNI) -> 
-                          Record(coef2 : polR, subResultant : polR)
-         ++ \axiom{semiIndiceSubResultantEuclidean(P, Q, i)} returns
-         ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
-         ++ \axiom{...P + coef2*Q = S_i(P,Q)}
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       degreeSubResultant : (polR, polR, NNI) -> polR
-         ++ \axiom{degreeSubResultant(P, Q, d)} computes 
-         ++ a subresultant of degree \axiom{d}.
-
-       degreeSubResultantEuclidean : (polR, polR, NNI) -> 
-                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
-         ++ \axiom{indiceSubResultant(P, Q, i)} returns
-         ++ a subresultant \axiom{S} of degree \axiom{d} 
-         ++ and carries out the equality \axiom{coef1*P + coef2*Q = S_i}.
-
-       semiDegreeSubResultantEuclidean : (polR, polR, NNI) -> 
-                          Record(coef2 : polR, subResultant : polR)
-         ++ \axiom{indiceSubResultant(P, Q, i)} returns
-         ++ a subresultant \axiom{S} of degree \axiom{d} 
-         ++ and carries out the equality \axiom{...P + coef2*Q = S_i}.
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       lastSubResultant : (polR, polR) -> polR
-         ++ \axiom{lastSubResultant(P, Q)} computes 
-         ++ the last non zero subresultant of \axiom{P} and \axiom{Q}
-
-       lastSubResultantEuclidean : (polR, polR) -> 
-                       Record(coef1 : polR, coef2 : polR, subResultant : polR)
-         ++ \axiom{lastSubResultantEuclidean(P, Q)} computes
-         ++ the last non zero subresultant \axiom{S} 
-         ++ and carries out the equality \axiom{coef1*P + coef2*Q = S}.
-
-       semiLastSubResultantEuclidean : (polR, polR) -> 
-                       Record(coef2 : polR, subResultant : polR)
-         ++ \axiom{semiLastSubResultantEuclidean(P, Q)} computes
-         ++ the last non zero subresultant \axiom{S} 
-         ++ and carries out the equality \axiom{...P + coef2*Q = S}.
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       subResultantGcd : (polR, polR) -> polR
-         ++ \axiom{subResultantGcd(P, Q)} returns the gcd 
-         ++ of two primitive polynomials \axiom{P} and \axiom{Q}.
-
-       subResultantGcdEuclidean : (polR, polR) 
-                     -> Record(coef1 : polR, coef2 : polR, gcd : polR)
-         ++ \axiom{subResultantGcdEuclidean(P,Q)} carries out the equality
-         ++ \axiom{coef1*P + coef2*Q = +/- S_i(P,Q)}
-         ++ where the degree (not the indice) 
-         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
-
-       semiSubResultantGcdEuclidean2 : (polR, polR) 
-                                   -> Record(coef2 : polR, gcd : polR)
-         ++ \axiom{semiSubResultantGcdEuclidean2(P,Q)} carries out the equality
-         ++ \axiom{...P + coef2*Q = +/- S_i(P,Q)}
-         ++ where the degree (not the indice) 
-         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       semiSubResultantGcdEuclidean1: (polR, polR)->Record(coef1: polR, gcd: polR)
-         ++ \axiom{semiSubResultantGcdEuclidean1(P,Q)} carries out the equality
-         ++ \axiom{coef1*P + ? Q = +/- S_i(P,Q)}
-         ++ where the degree (not the indice) 
-         ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
-
-       discriminant : polR -> R
-         ++ \axiom{discriminant(P, Q)} returns the discriminant 
-         ++ of \axiom{P} and \axiom{Q}.
-
-       discriminantEuclidean : polR -> 
-                           Record(coef1 : polR, coef2 : polR, discriminant : R)
-         ++ \axiom{discriminantEuclidean(P)} carries out the equality
-         ++ \axiom{coef1 * P + coef2 * D(P) = discriminant(P)}.
-
-       semiDiscriminantEuclidean : polR -> 
-                           Record(coef2 : polR, discriminant : R)
-         ++ \axiom{discriminantEuclidean(P)} carries out the equality
-         ++ \axiom{...P + coef2 * D(P) = discriminant(P)}.
-         ++ Warning: \axiom{degree(P) >= degree(Q)}.
-
-       chainSubResultants : (polR, polR) -> List(polR)
-         ++ \axiom{chainSubResultants(P, Q)} computes the list
-         ++ of non zero subresultants of \axiom{P} and \axiom{Q}.
-
-       schema : (polR, polR) -> List(NNI)
-         ++ \axiom{schema(P,Q)} returns the list of degrees of
-         ++ non zero subresultants of \axiom{P} and \axiom{Q}.
-
-       if R has GcdDomain then
-         resultantReduit : (polR, polR) -> R 
-         ++ \axiom{resultantReduit(P,Q)} returns the "reduce resultant"
-         ++ of \axiom{P} and \axiom{Q}.
-
-         resultantReduitEuclidean : (polR, polR) -> 
-                        Record(coef1 : polR, coef2 : polR, resultantReduit : R)
-         ++ \axiom{resultantReduitEuclidean(P,Q)} returns 
-         ++ the "reduce resultant" and carries out the equality
-         ++ \axiom{coef1*P + coef2*Q = resultantReduit(P,Q)}.
-
-         semiResultantReduitEuclidean : (polR, polR) -> 
-                        Record(coef2 : polR, resultantReduit : R)
-         ++ \axiom{semiResultantReduitEuclidean(P,Q)} returns 
-         ++ the "reduce resultant" and carries out the equality
-         ++ \axiom{...P + coef2*Q = resultantReduit(P,Q)}.
-
-         gcd : (polR, polR) -> polR 
-         ++ \axiom{gcd(P, Q)} returns the gcd of \axiom{P} and \axiom{Q}.
-       
-       -- sub-routines exported for convenience ----------------------------
-
-       "*" : (R, Vector(polR)) -> Vector(polR)
-         ++ \axiom{r * v} computes the product of \axiom{r} and \axiom{v}
-
-       "exquo" : (Vector(polR), R) -> Vector(polR)
-         ++ \axiom{v exquo r} computes 
-         ++ the exact quotient of \axiom{v} by \axiom{r}
-         
-       pseudoDivide : (polR, polR) -> 
-                                Record(coef:R, quotient:polR, remainder:polR)
-         ++ \axiom{pseudoDivide(P,Q)} computes the pseudoDivide 
-         ++ of \axiom{P} by \axiom{Q}.
-
-       divide : (polR, polR) -> Record(quotient : polR, remainder : polR)
-         ++ \axiom{divide(F,G)} computes quotient and rest 
-         ++ of the exact euclidean division of \axiom{F} by \axiom{G}.
-
-       Lazard : (R, R, NNI) -> R
-         ++ \axiom{Lazard(x, y, n)} computes \axiom{x**n/y**(n-1)}
-       
-       Lazard2 : (polR, R, R, NNI) -> polR
-         ++ \axiom{Lazard2(F, x, y, n)} computes  \axiom{(x/y)**(n-1) * F}
-         
-       next_sousResultant2 : (polR, polR, polR, R) -> polR
-         ++ \axiom{nextsousResultant2(P, Q, Z, s)} returns
-         ++ the subresultant \axiom{S_{e-1}} where
-         ++ \axiom{P ~ S_d,  Q = S_{d-1},  Z = S_e,  s = lc(S_d)}
-
-       resultant_naif : (polR, polR) -> R
-         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
-         ++ the resultant of \axiom{P} and \axiom{Q} computed 
-         ++ by means of the naive algorithm.
-
-       resultantEuclidean_naif : (polR, polR) -> 
-                          Record(coef1 : polR, coef2 : polR, resultant : R)
-         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
-         ++ the extended resultant of \axiom{P} and \axiom{Q} computed 
-         ++ by means of the naive algorithm.
-
-       semiResultantEuclidean_naif : (polR, polR) -> 
-                          Record(coef2 : polR, resultant : R)
-         ++ \axiom{resultantEuclidean_naif(P,Q)} returns 
-         ++ the semi-extended resultant of \axiom{P} and \axiom{Q} computed 
-         ++ by means of the naive algorithm.
-
-  Implementation == add
-    X : polR := monomial(1$R,1)
-
-    r : R * v : Vector(polR) == r::polR * v
-              -- the instruction  map(r * #1, v) is slower !?
-
-    v : Vector(polR) exquo r : R == map((#1 exquo r)::polR, v)
-
-    pseudoDivide(P : polR, Q : polR) : 
-                                 Record(coef:R,quotient:polR,remainder:polR) ==
-    -- computes the pseudoDivide of P by Q
-       zero?(Q) => error("PseudoDivide$PRS : division by 0")
-       zero?(P) => construct(1, 0, P)
-       lcQ : R := LC(Q)
-       (degP, degQ) := (degree(P), degree(Q))
-       degP < degQ => construct(1, 0, P)
-       Q := reductum(Q)
-       i : NNI := (degP - degQ + 1)::NNI
-       co : R := lcQ**i
-       quot : polR := 0$polR
-       while (delta : Integer := degree(P) - degQ) >= 0 repeat
-         i := (i - 1)::NNI
-         mon := monomial(LC(P), delta::NNI)$polR
-         quot := quot + lcQ**i * mon
-         P := lcQ * reductum(P) - mon * Q
-       P := lcQ**i * P
-       return construct(co, quot, P)
-
-    divide(F : polR, G : polR) : Record(quotient : polR, remainder : polR)==
-    -- computes quotient and rest of the exact euclidean division of F by G
-         lcG : R := LC(G)
-         degG : NNI := degree(G)
-         zero?(degG) => ( F := (F exquo lcG)::polR; return construct(F, 0))
-         G : polR := reductum(G)
-         quot : polR := 0
-         while (delta := degree(F) - degG) >= 0 repeat
-            mon : polR := monomial((LC(F) exquo lcG)::R, delta::NNI)
-            quot := quot + mon
-            F := reductum(F) - mon * G
-         return construct(quot, F)
-
-    resultant_naif(P : polR, Q : polR) : R ==
-    -- valid over a field
-       a : R := 1
-       repeat
-          zero?(Q) => return 0
-          (degP, degQ) := (degree(P), degree(Q))
-          if odd?(degP) and odd?(degQ) then a := - a
-          zero?(degQ) => return (a * LC(Q)**degP)
-          U : polR := divide(P, Q).remainder
-          a := a * LC(Q)**(degP - degree(U))::NNI
-          (P, Q) := (Q, U)
-
-    resultantEuclidean_naif(P : polR, Q : polR) :
-                       Record(coef1 : polR, coef2 : polR, resultant : R) ==
-    -- valid over a field.
-       a : R := 1
-       old_cf1 : polR := 1 ; cf1 : polR := 0
-       old_cf2 : polR := 0 ; cf2 : polR := 1
-       repeat
-          zero?(Q) => construct(0::polR, 0::polR, 0::R)
-          (degP, degQ) := (degree(P), degree(Q))
-          if odd?(degP) and odd?(degQ) then a := -a
-          if zero?(degQ) then
-             a := a * LC(Q)**(degP-1)::NNI
-             return construct(a*cf1, a*cf2, a*LC(Q))
-          divid := divide(P,Q)
-          a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
-          (P, Q) := (Q, divid.remainder)
-          (old_cf1, old_cf2, cf1, cf2) := (cf1, cf2, 
-                old_cf1 - divid.quotient * cf1, old_cf2 - divid.quotient * cf2)
-
-    semiResultantEuclidean_naif(P : polR, Q : polR) :
-                       Record(coef2 : polR, resultant : R) ==
-    -- valid over a field
-       a : R := 1
-       old_cf2 : polR := 0 ; cf2 : polR := 1
-       repeat
-          zero?(Q) => construct(0::polR, 0::R)
-          (degP, degQ) := (degree(P), degree(Q))
-          if odd?(degP) and odd?(degQ) then a := -a
-          if zero?(degQ) then
-             a := a * LC(Q)**(degP-1)::NNI
-             return construct(a*cf2, a*LC(Q))
-          divid := divide(P,Q)
-          a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
-          (P, Q) := (Q, divid.remainder)
-          (old_cf2, cf2) := (cf2, old_cf2 - divid.quotient * cf2)
-
-    Lazard(x : R, y : R, n : NNI) : R ==
-       zero?(n) => error("Lazard$PRS : n = 0")
---       one?(n) => x
-       (n = 1) => x
-       a : NNI := 1
-       while n >= (b := 2*a) repeat a := b
-       c : R := x
-       n := (n - a)::NNI
-       repeat                    --  c = x**i / y**(i-1),  i=n_0 quo a,  a=2**?
---          one?(a) => return c
-          (a = 1) => return c
-          a := a quo 2
-          c := ((c * c) exquo y)::R
-          if n >= a then ( c := ((c * x) exquo y)::R ; n := (n - a)::NNI )
-
-    Lazard2(F : polR, x : R, y : R, n : NNI) : polR ==
-       zero?(n) => error("Lazard2$PRS : n = 0")
---       one?(n) => F
-       (n = 1) => F
-       x := Lazard(x, y, (n-1)::NNI)
-       return ((x * F) exquo y)::polR
-
-    Lazard3(V : Vector(polR), x : R, y : R, n : NNI) : Vector(polR) ==
-    -- computes x**(n-1) * V / y**(n-1)
-       zero?(n) => error("Lazard2$prs : n = 0")
---       one?(n) => V
-       (n = 1) => V
-       x := Lazard(x, y, (n-1)::NNI)
-       return ((x * V) exquo y)
-
-    next_sousResultant2(P : polR, Q : polR, Z : polR, s : R) : polR ==
-       (lcP, c, se) := (LC(P), LC(Q), LC(Z))
-       (d, e) := (degree(P), degree(Q))
-       (P, Q, H) := (reductum(P), reductum(Q), - reductum(Z))
-       A : polR := coefficient(P, e) * H
-       for i in e+1..d-1 repeat 
-          H := if degree(H) = e-1 then  
-                  X * reductum(H) - ((LC(H) * Q) exquo c)::polR
-               else
-                  X * H
-          -- H = s_e * X^i mod S_d-1
-          A := coefficient(P, i) * H + A
-       while degree(P) >= e repeat P := reductum(P)
-       A := A + se * P            --  A = s_e * reductum(P_0)       mod S_d-1
-       A := (A exquo lcP)::polR   --  A = s_e * reductum(S_d) / s_d mod S_d-1
-       A := if degree(H) = e-1 then 
-               c * (X * reductum(H) + A) - LC(H) * Q
-            else
-               c * (X * H + A)
-       A := (A exquo s)::polR                    -- A = +/- S_e-1
-       return (if odd?(d-e) then A else - A)
-
-    next_sousResultant3(VP : Vector(polR), VQ : Vector(polR), s : R, ss : R) :
-                                                      Vector(polR) ==
-    -- P ~ S_d,  Q = S_d-1,  s = lc(S_d),  ss = lc(S_e)
-       (P, Q) := (VP.1, VQ.1)
-       (lcP, c) := (LC(P), LC(Q))
-       e : NNI := degree(Q)
---       if one?(delta := degree(P) - e) then                   -- algo_new
-       if ((delta := degree(P) - e) = 1) then                   -- algo_new
-         VP := c * VP - coefficient(P, e) * VQ
-         VP := VP exquo lcP
-         VP := c * (VP - X * VQ) + coefficient(Q, (e-1)::NNI) * VQ
-         VP := VP exquo s
-       else                                    -- algorithm of Lickteig - Roy
-         (r, rr) := (s * lcP, ss * c)
-         divid := divide(rr * P, Q)
-         VP.1 := (divid.remainder exquo r)::polR
-         for i in 2..#VP repeat
-           VP.i := rr * VP.i - VQ.i * divid.quotient
-           VP.i := (VP.i exquo r)::polR
-       return (if odd?(delta) then VP else - VP)
-
-    algo_new(P : polR, Q : polR) : R ==
-       delta : NNI := (degree(P) - degree(Q))::NNI
-       s : R := LC(Q)**delta
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       repeat      
-          -- P = S_c-1 (except the first turn : P ~ S_c-1), 
-          -- Q = S_d-1,  s = lc(S_d)
-          zero?(Q) => return 0
-          delta := (degree(P) - degree(Q))::NNI
-          Z : polR := Lazard2(Q, LC(Q), s, delta)          
-          -- Z = S_e ~ S_d-1
-          zero?(degree(Z)) => return LC(Z)
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    resultant(P : polR, Q : polR) : R ==
-       zero?(Q) or zero?(P) => 0
-       if degree(P) < degree(Q) then 
-          (P, Q) := (Q, P)
-          if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
-       zero?(degree(Q)) => LC(Q)**degree(P)
-       -- degree(P) >= degree(Q) > 0
-       R has Finite => resultant_naif(P, Q)
-       return algo_new(P, Q)
-
-    subResultantEuclidean(P : polR, Q : polR) :
-                          Record(coef1 : polR, coef2 : polR, resultant : R) ==
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 0::polR, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(0::polR, 0::polR, 0::R)
-          e : NNI := degree(Q)
-          delta : NNI := (degree(P) - e)::NNI
-          if zero?(e) then
-             l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
-             return construct(l.2, l.3, LC(l.1))
-          ss : R := Lazard(LC(Q), s, delta)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    resultantEuclidean(P : polR, Q : polR) : 
-                       Record(coef1 : polR, coef2 : polR, resultant : R) ==
-       zero?(P) or zero?(Q) => construct(0::polR, 0::polR, 0::R)
-       if degree(P) < degree(Q) then 
-          e : Integer := if odd?(degree(P)) and odd?(degree(Q)) then -1 else 1
-          l := resultantEuclidean(Q, e * P)
-          return construct(e * l.coef2, l.coef1, l.resultant)
-       if zero?(degree(Q)) then
-          degP : NNI := degree(P)
-          zero?(degP) => error("resultantEuclidean$PRS : constant polynomials")
-          s : R := LC(Q)**(degP-1)::NNI
-          return construct(0::polR, s::polR, s * LC(Q))
-       R has Finite => resultantEuclidean_naif(P, Q)
-       return subResultantEuclidean(P,Q)
-
-    semiSubResultantEuclidean(P : polR, Q : polR) :
-                       Record(coef2 : polR, resultant : R) ==
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(0::polR, 0::R)
-          e : NNI := degree(Q)
-          delta : NNI := (degree(P) - e)::NNI
-          if zero?(e) then
-             l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
-             return construct(l.2, LC(l.1))
-          ss : R := Lazard(LC(Q), s, delta)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiResultantEuclidean2(P : polR, Q : polR) : 
-                       Record(coef2 : polR, resultant : R) ==
-       zero?(P) or zero?(Q) => construct(0::polR, 0::R)
-       degree(P) < degree(Q) => error("semiResultantEuclidean2 : bad degrees")
-       if zero?(degree(Q)) then
-          degP : NNI := degree(P)
-          zero?(degP) => error("semiResultantEuclidean2 : constant polynomials")
-          s : R := LC(Q)**(degP-1)::NNI
-          return construct(s::polR, s * LC(Q))
-       R has Finite => semiResultantEuclidean_naif(P, Q)
-       return semiSubResultantEuclidean(P,Q)
-
-    semiResultantEuclidean1(P : polR, Q : polR) :
-                       Record(coef1 : polR, resultant : R) ==
-       result := resultantEuclidean(P,Q)
-       [result.coef1, result.resultant]
-
-    indiceSubResultant(P : polR, Q : polR, i : NNI) : polR == 
-       zero?(Q) or zero?(P) => 0
-       if degree(P) < degree(Q) then 
-          (P, Q) := (Q, P)
-          if odd?(degree(P)-i) and odd?(degree(Q)-i) then Q := - Q
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => error("indiceSubResultant$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return s*Q
-       i > degree(Q) => 0
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       repeat
-          -- P = S_{c-1} ~ S_d , Q = S_{d-1},  s = lc(S_d),  i < d
-          (degP, degQ) := (degree(P), degree(Q))
-          i = degP-1 => return Q
-          zero?(Q) or (i > degQ) => return 0
-          Z : polR := Lazard2(Q, LC(Q), s, (degP - degQ)::NNI)
-          --  Z = S_e ~ S_d-1
-          i = degQ => return Z
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    indiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
-                    Record(coef1 : polR, coef2 : polR, subResultant : polR) == 
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
-       if degree(P) < degree(Q) then 
-          e := if odd?(degree(P)-i) and odd?(degree(Q)-i) then -1 else 1
-          l := indiceSubResultantEuclidean(Q, e * P, i)
-          return construct(e * l.coef2, l.coef1, l.subResultant)
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => 
-                      error("indiceSubResultantEuclidean$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return construct(0::polR, s::polR, s * Q)
-       i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 0::polR, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d),  i < d
-          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(0::polR, 0::polR, 0::polR)
-          (degP, degQ) := (degree(P), degree(Q))
-          i = degP-1 => return construct(VQ.2, VQ.3, VQ.1)
-          (i > degQ) => return construct(0::polR, 0::polR, 0::polR)
-          VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
-          i = degQ => return construct(VZ.2, VZ.3, VZ.1)
-          ss : R := LC(VZ.1)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiIndiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
-                    Record(coef2 : polR, subResultant : polR) == 
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
-       degree(P) < degree(Q) => 
-                  error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => 
-                  error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return construct(s::polR, s * Q)
-       i > degree(Q) => construct(0::polR, 0::polR)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d),  i < d
-          --  S_{c-1} = ...P_0 + VP.2 Q_0,  S_{d-1} = ...P_0 + ...Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(0::polR, 0::polR)
-          (degP, degQ) := (degree(P), degree(Q))
-          i = degP-1 => return construct(VQ.2, VQ.1)
-          (i > degQ) => return construct(0::polR, 0::polR)
-          VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
-          i = degQ => return construct(VZ.2, VZ.1)
-          ss : R := LC(VZ.1)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    degreeSubResultant(P : polR, Q : polR, i : NNI) : polR == 
-       zero?(Q) or zero?(P) => 0
-       if degree(P) < degree(Q) then (P, Q) := (Q, P)
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => error("degreeSubResultant$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return s*Q
-       i > degree(Q) => 0
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       repeat
-          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
-          zero?(Q) or (i > degree(Q)) => return 0
-          i = degree(Q) => return Q
-          Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
-          --  Z = S_e ~ S_d-1
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    degreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) : 
-                     Record(coef1 : polR, coef2 : polR, subResultant : polR) ==
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
-       if degree(P) < degree(Q) then 
-          l := degreeSubResultantEuclidean(Q, P, i)
-          return construct(l.coef2, l.coef1, l.subResultant)
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => 
-                      error("degreeSubResultantEuclidean$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return construct(0::polR, s::polR, s * Q)
-       i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 0::polR, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) or (i > degree(Q)) => 
-               return construct(0::polR, 0::polR, 0::polR)
-          i = degree(Q) => return construct(VQ.2, VQ.3, VQ.1)
-          ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiDegreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) : 
-                     Record(coef2 : polR, subResultant : polR) ==
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
-       degree(P) < degree(Q) =>
-                  error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
-       if i = degree(Q) then
-          delta : NNI := (degree(P)-degree(Q))::NNI
-          zero?(delta) => 
-                  error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
-          s : R := LC(Q)**(delta-1)::NNI
-          return construct(s::polR, s * Q)
-       i > degree(Q) => construct(0::polR, 0::polR)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = ...P_0 + VP.3 Q_0,  S_{d-1} = ...P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) or (i > degree(Q)) => 
-               return construct(0::polR, 0::polR)
-          i = degree(Q) => return construct(VQ.2, VQ.1)
-          ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    lastSubResultant(P : polR, Q : polR) : polR ==
-       zero?(Q) or zero?(P) => 0
-       if degree(P) < degree(Q) then (P, Q) := (Q, P)
-       zero?(degree(Q)) => (LC(Q)**degree(P))::polR
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       Z : polR := P
-       repeat
-          -- Z = S_d  (except the first turn : Z = P)
-          -- P = S_{c-1} ~ S_d,  Q = S_{d-1},  s = lc(S_d)
-          zero?(Q) => return Z
-          Z := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
-          -- Z = S_e ~ S_{d-1}
-          zero?(degree(Z)) => return Z
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    lastSubResultantEuclidean(P : polR, Q : polR) :
-                    Record(coef1 : polR, coef2 : polR, subResultant : polR) == 
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
-       if degree(P) < degree(Q) then 
-          l := lastSubResultantEuclidean(Q, P)
-          return construct(l.coef2, l.coef1, l.subResultant)
-       if zero?(degree(Q)) then
-          degP : NNI := degree(P)
-          zero?(degP) => 
-              error("lastSubResultantEuclidean$PRS : constant polynomials")
-          s : R := LC(Q)**(degP-1)::NNI
-          return construct(0::polR, s::polR, s * Q)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 0::polR, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
-       VZ : Vector(polR) := copy(VP)
-       repeat
-          --  VZ.1 = S_d,  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d)
-          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0
-          --  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
-          --  S_d     = VZ.2 P_0 + VZ.3 Q_0
-          (Q, Z) := (VQ.1, VZ.1)
-          zero?(Q) => return construct(VZ.2, VZ.3, VZ.1)
-          VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
-          zero?(degree(Q)) => return construct(VZ.2, VZ.3, VZ.1)
-          ss : R := LC(VZ.1)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiLastSubResultantEuclidean(P : polR, Q : polR) :
-                    Record(coef2 : polR, subResultant : polR) == 
-       zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
-       degree(P) < degree(Q) =>
-              error("semiLastSubResultantEuclidean$PRS : bad degrees")
-       if zero?(degree(Q)) then
-          degP : NNI := degree(P)
-          zero?(degP) => 
-              error("semiLastSubResultantEuclidean$PRS : constant polynomials")
-          s : R := LC(Q)**(degP-1)::NNI
-          return construct(s::polR, s * Q)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
-       VZ : Vector(polR) := copy(VP)
-       repeat
-          --  VZ.1 = S_d,  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s = lc(S_d)
-          --  S_{c-1} = ... P_0 + VP.2 Q_0
-          --  S_{d-1} = ... P_0 + VQ.2 Q_0
-          --  S_d     = ... P_0 + VZ.2 Q_0
-          (Q, Z) := (VQ.1, VZ.1)
-          zero?(Q) => return construct(VZ.2, VZ.1)
-          VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
-          zero?(degree(Q)) => return construct(VZ.2, VZ.1)
-          ss : R := LC(VZ.1)
-          (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    chainSubResultants(P : polR, Q : polR) : List(polR) ==
-       zero?(Q) or zero?(P) => []
-       if degree(P) < degree(Q) then 
-          (P, Q) := (Q, P)
-          if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
-       L : List(polR) := []
-       zero?(degree(Q)) => L
-       L := [Q]
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       repeat
-          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
-          -- L = [S_d,....,S_{q-1}]
-          zero?(Q) => return L
-          L := concat(Q, L)
-          -- L = [S_{d-1},....,S_{q-1}]
-          delta : NNI := (degree(P) - degree(Q))::NNI
-          Z : polR := Lazard2(Q, LC(Q), s, delta)            -- Z = S_e ~ S_d-1
-          if delta > 1 then L := concat(Z, L)
-          -- L = [S_e,....,S_{q-1}]
-          zero?(degree(Z)) => return L
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    schema(P : polR, Q : polR) : List(NNI) ==
-       zero?(Q) or zero?(P) => []
-       if degree(P) < degree(Q) then (P, Q) := (Q, P)
-       zero?(degree(Q)) => [0]
-       L : List(NNI) := []
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, Q))
-       repeat
-          -- P = S_{c-1} ~ S_d,  Q = S_{d-1},  s = lc(S_d)
-          zero?(Q) => return L
-          e : NNI := degree(Q)
-          L := concat(e, L)
-          delta : NNI := (degree(P) - e)::NNI
-          Z : polR := Lazard2(Q, LC(Q), s, delta)            -- Z = S_e ~ S_d-1
-          if delta > 1 then L := concat(e, L)
-          zero?(e) => return L
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-
-    subResultantGcd(P : polR, Q : polR) : polR == 
-       zero?(P) and zero?(Q) => 0
-       zero?(P) => Q
-       zero?(Q) => P
-       if degree(P) < degree(Q) then (P, Q) := (Q, P)
-       zero?(degree(Q)) => 1$polR
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       (P, Q) := (Q, pseudoRemainder(P, -Q))
-       repeat
-          -- P = S_{c-1},  Q = S_{d-1},  s = lc(S_d)
-          zero?(Q) => return P
-          zero?(degree(Q)) => return 1$polR
-          Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI) 
-          -- Z = S_e ~ S_d-1
-          (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
-          s := LC(Z)
-            
-    subResultantGcdEuclidean(P : polR, Q : polR) :
-                    Record(coef1 : polR, coef2 : polR, gcd : polR) ==
-       zero?(P) and zero?(Q) => construct(0::polR, 0::polR, 0::polR)
-       zero?(P) => construct(0::polR, 1::polR, Q)
-       zero?(Q) => construct(1::polR, 0::polR, P)
-       if degree(P) < degree(Q) then 
-          l := subResultantGcdEuclidean(Q, P)
-          return construct(l.coef2, l.coef1, l.gcd)
-       zero?(degree(Q)) => construct(0::polR, 1::polR, Q)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 0::polR, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
-       repeat
-          --  VP.1 = S_{c-1},  VQ.1 = S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = VP.2 P_0 + VP.3 Q_0,  S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(VP.2, VP.3, P)
-          e : NNI := degree(Q)
-          zero?(e) => return construct(VQ.2, VQ.3, Q)
-          ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
-          (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiSubResultantGcdEuclidean2(P : polR, Q : polR) :
-                                  Record(coef2 : polR, gcd : polR) ==
-       zero?(P) and zero?(Q) => construct(0::polR, 0::polR)
-       zero?(P) => construct(1::polR, Q)
-       zero?(Q) => construct(0::polR, P)
-       degree(P) < degree(Q) => 
-                       error("semiSubResultantGcdEuclidean2$PRS : bad degrees")
-       zero?(degree(Q)) => construct(1::polR, Q)
-       s : R := LC(Q)**(degree(P) - degree(Q))::NNI
-       VP : Vector(polR) := [Q, 1::polR]
-       pdiv := pseudoDivide(P, -Q)
-       VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
-       repeat
-          --  P=S_{c-1},  Q=S_{d-1},  s=lc(S_d)
-          --  S_{c-1} = ? P_0 + old_cf2 Q_0,  S_{d-1} = ? P_0 + cf2 Q_0
-          (P, Q) := (VP.1, VQ.1)
-          zero?(Q) => return construct(VP.2, P)
-          e : NNI := degree(Q)
-          zero?(e) => return construct(VQ.2, Q)
-          ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
-          (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
-          s := ss
-
-    semiSubResultantGcdEuclidean1(P : polR, Q : polR) :
-                       Record(coef1 : polR, gcd : polR) ==
-       result := subResultantGcdEuclidean(P,Q)
-       [result.coef1, result.gcd]
-
-    discriminant(P : polR) : R ==
-       d : Integer := degree(P)
-       zero?(d) => error "cannot take discriminant of constants"
-       a : Integer := (d * (d-1)) quo 2
-       a := (-1)**a::NonNegativeInteger
-       dP : polR := differentiate P
-       r : R := resultant(P, dP)
-       d := d - degree(dP) - 1
-       return (if zero?(d) then a * (r exquo LC(P))::R
-               else a * r * LC(P)**(d-1)::NNI)
-
-    discriminantEuclidean(P : polR) : 
-                       Record(coef1 : polR, coef2 : polR, discriminant : R) ==
-       d : Integer := degree(P)
-       zero?(d) => error "cannot take discriminant of constants"
-       a : Integer := (d * (d-1)) quo 2
-       a := (-1)**a::NonNegativeInteger
-       dP : polR := differentiate P
-       rE := resultantEuclidean(P, dP)
-       d := d - degree(dP) - 1
-       if zero?(d) then 
-          c1 : polR := a * (rE.coef1 exquo LC(P))::polR
-          c2 : polR := a * (rE.coef2 exquo LC(P))::polR
-          cr : R := a * (rE.resultant exquo LC(P))::R
-       else
-          c1 : polR := a * rE.coef1 * LC(P)**(d-1)::NNI
-          c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
-          cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
-       return construct(c1, c2, cr)
-
-    semiDiscriminantEuclidean(P : polR) : 
-                            Record(coef2 : polR, discriminant : R) ==
-       d : Integer := degree(P)
-       zero?(d) => error "cannot take discriminant of constants"
-       a : Integer := (d * (d-1)) quo 2
-       a := (-1)**a::NonNegativeInteger
-       dP : polR := differentiate P
-       rE := semiResultantEuclidean2(P, dP)
-       d := d - degree(dP) - 1
-       if zero?(d) then 
-          c2 : polR := a * (rE.coef2 exquo LC(P))::polR
-          cr : R := a * (rE.resultant exquo LC(P))::R
-       else
-          c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
-          cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
-       return construct(c2, cr)
-
-    if R has GcdDomain then
-       resultantReduit(P : polR, Q : polR) : R ==
-          UV := subResultantGcdEuclidean(P, Q)
-          UVs : polR := UV.gcd
-          degree(UVs) > 0 => 0
-          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
-          return (LC(UVs) exquo gcd(l))::R
-
-       resultantReduitEuclidean(P : polR, Q : polR) :
-                     Record(coef1 : polR, coef2 : polR, resultantReduit : R) ==
-          UV := subResultantGcdEuclidean(P, Q)
-          UVs : polR := UV.gcd
-          degree(UVs) > 0 => construct(0::polR, 0::polR, 0::R)
-          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
-          gl : R := gcd(l)
-          c1 : polR := (UV.coef1 exquo gl)::polR
-          c2 : polR := (UV.coef2 exquo gl)::polR
-          rr : R := (LC(UVs) exquo gl)::R
-          return construct(c1, c2, rr)
-
-       semiResultantReduitEuclidean(P : polR, Q : polR) :
-                                   Record(coef2 : polR, resultantReduit : R) ==
-          UV := subResultantGcdEuclidean(P, Q)
-          UVs : polR := UV.gcd
-          degree(UVs) > 0 => construct(0::polR, 0::R)
-          l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
-          gl : R := gcd(l)
-          c2 : polR := (UV.coef2 exquo gl)::polR
-          rr : R := (LC(UVs) exquo gl)::R
-          return construct(c2, rr)
-
-       gcd_naif(P : polR, Q : polR) : polR ==
-       -- valid over a field
-          zero?(P) => (Q exquo LC(Q))::polR
-          repeat
-             zero?(Q) => return (P exquo LC(P))::polR
-             zero?(degree(Q)) => return 1$polR
-             (P, Q) := (Q, divide(P, Q).remainder)
-
-       gcd(P : polR, Q : polR) : polR ==
-          R has Finite => gcd_naif(P,Q) 
-          zero?(P) => Q
-          zero?(Q) => P
-          cP : R := content(P)
-          cQ : R := content(Q)
-          P := (P exquo cP)::polR
-          Q := (Q exquo cQ)::polR
-          G : polR := subResultantGcd(P, Q)
-          return gcd(cP,cQ) * primitivePart(G)
-
-@
-\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 PRS PseudoRemainderSequence>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/pseudolin.spad.pamphlet b/src/algebra/pseudolin.spad.pamphlet
deleted file mode 100644
index 3eb384b..0000000
--- a/src/algebra/pseudolin.spad.pamphlet
+++ /dev/null
@@ -1,208 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra pseudolin.spad}
-\author{Bruno Zuercher}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package PSEUDLIN PseudoLinearNormalForm}
-<<package PSEUDLIN PseudoLinearNormalForm>>=
-)abbrev package PSEUDLIN PseudoLinearNormalForm
-++ Normal forms of pseudo-linear operators
-++ Author: Bruno Zuercher
-++ Date Created: November 1993
-++ Date Last Updated: 12 April 1994
-++ Description:
-++   PseudoLinearNormalForm provides a function for computing a block-companion
-++   form for pseudo-linear operators.
-PseudoLinearNormalForm(K:Field): Exports == Implementation where
-  ER  ==> Record(C: Matrix K, g: Vector K)
-  REC ==> Record(R: Matrix K, A: Matrix K, Ainv: Matrix K)
-
-  Exports ==> with
-    normalForm: (Matrix K, Automorphism K, K -> K) -> REC
-      ++ normalForm(M, sig, der) returns \spad{[R, A, A^{-1}]} such that
-      ++ the pseudo-linear operator whose matrix in the basis \spad{y} is
-      ++ \spad{M} had matrix \spad{R} in the basis \spad{z = A y}.
-      ++ \spad{der} is a \spad{sig}-derivation.
-    changeBase: (Matrix K, Matrix K, Automorphism K, K -> K) -> Matrix K
-      ++ changeBase(M, A, sig, der): computes the new matrix of a pseudo-linear
-      ++ transform given by the matrix M under the change of base A
-    companionBlocks: (Matrix K, Vector K) -> List ER
-      ++ companionBlocks(m, v) returns \spad{[[C_1, g_1],...,[C_k, g_k]]}
-      ++ such that each \spad{C_i} is a companion block and
-      ++ \spad{m = diagonal(C_1,...,C_k)}.
-
-  Implementation ==> add
-    normalForm0: (Matrix K, Automorphism K, Automorphism K, K -> K) -> REC
-    mulMatrix: (Integer, Integer, K) -> Matrix K
-      -- mulMatrix(N, i, a): under a change of base with the resulting matrix of
-      -- size N*N the following operations are performed:
-      -- D1: column i will be multiplied by sig(a)
-      -- D2: row i will be multiplied by 1/a
-      -- D3: addition of der(a)/a to the element at position (i,i)
-    addMatrix: (Integer, Integer, Integer, K) -> Matrix K
-      -- addMatrix(N, i, k, a): under a change of base with the resulting matrix
-      -- of size N*N the following operations are performed:
-      -- C1: addition of column i multiplied by sig(a) to column k
-      -- C2: addition of row k multiplied by -a to row i
-      -- C3: addition of -a*der(a) to the element at position (i,k)
-    permutationMatrix: (Integer, Integer, Integer) -> Matrix K
-      -- permutationMatrix(N, i, k): under a change of base with the resulting
-      -- permutation matrix of size N*N the following operations are performed:
-      -- P1: columns i and k will be exchanged
-      -- P2: rows i and k will be exchanged
-    inv: Matrix K -> Matrix K
-      -- inv(M): computes the inverse of a invertable matrix M.
-      -- avoids possible type conflicts
-
-    inv m                      == inverse(m) :: Matrix K
-    changeBase(M, A, sig, der) == inv(A) * (M * map(sig #1, A) + map(der, A))
-    normalForm(M, sig, der)    == normalForm0(M, sig, inv sig, der)
-
-    companionBlocks(R, w) ==
-      -- decomposes the rational matrix R into single companion blocks
-      -- and the inhomogenity w as well
-      i:Integer := 1
-      n := nrows R
-      l:List(ER) := empty()
-      while i <= n repeat
-        j := i
-        while j+1 <= n and R(j,j+1) = 1 repeat j := j+1
-        --split block now
-        v:Vector K := new((j-i+1)::NonNegativeInteger, 0)
-        for k in i..j repeat v(k-i+1) := w k
-        l := concat([subMatrix(R,i,j,i,j), v], l)
-        i := j+1
-      l
-
-    normalForm0(M, sig, siginv, der) ==
-      -- the changes of base will be incremented in B and Binv,
-      -- where B**(-1)=Binv; E defines an elementary matrix
-      B, Binv, E    : Matrix K
-      recOfMatrices : REC
-      N := nrows M
-      B := diagonalMatrix [1 for k in 1..N]
-      Binv := copy B
-      -- avoid unnecessary recursion
-      if diagonal?(M) then return [M, B, Binv]
-      i : Integer := 1
-      while i < N repeat
-        j := i + 1
-        while j <= N and M(i, j) = 0 repeat  j := j + 1
-        if j <= N then
-          -- expand companionblock by lemma 5
-          if j ^= i+1 then
-            -- perform first a permutation
-            E := permutationMatrix(N, i+1, j)
-            M := changeBase(M, E, sig, der)
-            B := B*E
-            Binv := E*Binv
-          -- now is M(i, i+1) ^= 0
-          E := mulMatrix(N, i+1, siginv inv M(i,i+1))
-          M := changeBase(M, E, sig, der)
-          B := B*E
-          Binv := inv(E)*Binv
-          for j in 1..N repeat
-            if j ^= i+1 then
-              E := addMatrix(N, i+1, j, siginv(-M(i,j)))
-              M := changeBase(M, E, sig, der)
-              B := B*E
-              Binv := inv(E)*Binv
-          i := i + 1
-        else
-          -- apply lemma 6
-          for j in i..2 by -1 repeat
-            for k in (i+1)..N repeat
-              E := addMatrix(N, k, j-1, M(k,j))
-              M := changeBase(M, E, sig, der)
-              B := B*E
-              Binv := inv(E)*Binv
-          j := i + 1
-          while j <= N and M(j,1) = 0 repeat  j := j + 1
-          if j <= N then
-            -- expand companionblock by lemma 8
-            E := permutationMatrix(N, 1, j)
-            M := changeBase(M, E, sig, der)
-            B := B*E
-            Binv := E*Binv
-            -- start again to establish rational form
-            i := 1
-          else
-            -- split a direct factor
-            recOfMatrices :=
-              normalForm(subMatrix(M, i+1, N, i+1, N), sig, der)
-            setsubMatrix!(M, i+1, i+1, recOfMatrices.R)
-            E := diagonalMatrix [1 for k in 1..N]
-            setsubMatrix!(E, i+1, i+1, recOfMatrices.A)
-            B := B*E
-            setsubMatrix!(E, i+1, i+1, recOfMatrices.Ainv)
-            Binv := E*Binv
-            -- M in blockdiagonalform, stop program
-            i := N
-      [M, B, Binv]
-
-    mulMatrix(N, i, a) ==
-      M : Matrix K := diagonalMatrix [1 for j in 1..N]
-      M(i, i) := a
-      M
-
-    addMatrix(N, i, k, a) ==
-      A : Matrix K := diagonalMatrix [1 for j in 1..N]
-      A(i, k) := a
-      A
-
-    permutationMatrix(N, i, k) ==
-      P : Matrix K := diagonalMatrix [1 for j in 1..N]
-      P(i, i) := P(k, k) := 0
-      P(i, k) := P(k, i) := 1
-      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 PSEUDLIN PseudoLinearNormalForm>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/puiseux.spad.pamphlet b/src/algebra/puiseux.spad.pamphlet
deleted file mode 100644
index ab53530..0000000
--- a/src/algebra/puiseux.spad.pamphlet
+++ /dev/null
@@ -1,90 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra puiseux.spad}
-\author{Clifton J. Williamson, Scott C. Morrison}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package UPXS2 UnivariatePuiseuxSeriesFunctions2}
-<<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>=
-)abbrev package UPXS2 UnivariatePuiseuxSeriesFunctions2
-++ Mapping package for univariate Puiseux series
-++ Author: Scott C. Morrison
-++ Date Created: 5 April 1991
-++ Date Last Updated: 5 April 1991
-++ Keywords: Puiseux series, map
-++ Examples:
-++ References:
-++ Description:
-++   Mapping package for univariate Puiseux series.
-++   This package allows one to apply a function to the coefficients of
-++   a univariate Puiseux series.
-UnivariatePuiseuxSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
- Exports == Implementation where
-  Coef1 : Ring
-  Coef2 : Ring
-  var1: Symbol
-  var2: Symbol
-  cen1: Coef1
-  cen2: Coef2
-  UPS1  ==> UnivariatePuiseuxSeries(Coef1, var1, cen1)
-  UPS2  ==> UnivariatePuiseuxSeries(Coef2, var2, cen2)
-  ULSP2 ==> UnivariateLaurentSeriesFunctions2(Coef1, Coef2, var1, var2, cen1, cen2)
-
-  Exports ==> with
-    map: (Coef1 -> Coef2,UPS1) -> UPS2
-      ++ \spad{map(f,g(x))} applies the map f to the coefficients of the
-      ++ Puiseux series \spad{g(x)}.
-
-  Implementation ==> add
-
-    map(f,ups) == puiseux(rationalPower ups, map(f, laurentRep ups)$ULSP2)
-
-@
-\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 UPXS2 UnivariatePuiseuxSeriesFunctions2>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html
index 1b1365b..85a69c9 100644
--- a/src/axiom-website/patches.html
+++ b/src/axiom-website/patches.html
@@ -929,5 +929,7 @@ bookvol10.4 add packages<br/>
 bookvol10.4 add packages<br/>
 <a href="patches/20090207.02.tpd.patch">20090207.02.tpd.patch</a>
 bookvol10.4 add packages<br/>
+<a href="patches/20090208.01.tpd.patch">20090208.01.tpd.patch</a>
+bookvol10.4 add packages<br/>
  </body>
 </html>
