diff --git a/books/bookvol10.4.pamphlet b/books/bookvol10.4.pamphlet
index b3218e2..5d563d8 100644
--- a/books/bookvol10.4.pamphlet
+++ b/books/bookvol10.4.pamphlet
@@ -3575,6 +3575,45 @@ AnyFunctions1(S:Type): with
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package APPLYORE ApplyUnivariateSkewPolynomial}
+\pagehead{ApplyUnivariateSkewPolynomial}{APPLYORE}
+\pagepic{ps/v104applyunivariateskewpolynomial.ps}{APPLYORE}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package APPLYORE ApplyUnivariateSkewPolynomial>>=
+)abbrev package APPLYORE ApplyUnivariateSkewPolynomial
+++ Author: Manuel Bronstein
+++ Date Created: 7 December 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++   \spad{ApplyUnivariateSkewPolynomial} (internal) allows univariate
+++   skew polynomials to be applied to appropriate modules.
+ApplyUnivariateSkewPolynomial(R:Ring, M: LeftModule R,
+    P: UnivariateSkewPolynomialCategory R): with
+      apply: (P, M -> M, M) -> M
+        ++ apply(p, f, m) returns \spad{p(m)} where the action is given
+        ++ by \spad{x m = f(m)}.
+        ++ \spad{f} must be an R-pseudo linear map on M.
+   == add
+      apply(p, f, m) ==
+        w:M  := 0
+        mn:M := m
+        for i in 0..degree p repeat
+          w  := w + coefficient(p, i) * mn
+          mn := f mn
+        w
+
+@
+<<APPLYORE.dotabb>>=
+"APPLYORE" [color="#FF4488",href="bookvol10.4.pdf#nameddest=APPLYORE"]
+"OREPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OREPCAT"]
+"APPLYORE" -> "OREPCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ASSOCEQ AssociatedEquations}
 \pagehead{AssociatedEquations}{ASSOCEQ}
 \pagepic{ps/v104associatedequations.ps}{ASSOCEQ}{1.00}
@@ -4442,6 +4481,199 @@ input.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter B}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package BALFACT BalancedFactorisation}
+\pagehead{BalancedFactorisation}{BALFACT}
+\pagepic{ps/v104balancedfactorisation.ps}{BALFACT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package BALFACT BalancedFactorisation>>=
+)abbrev package BALFACT BalancedFactorisation
+++ Author: Manuel Bronstein
+++ Date Created: 1 March 1991
+++ Date Last Updated: 11 October 1991
+++ Description: This package provides balanced factorisations of polynomials.
+BalancedFactorisation(R, UP): Exports == Implementation where
+  R  : Join(GcdDomain, CharacteristicZero)
+  UP : UnivariatePolynomialCategory R
+
+  Exports ==> with
+    balancedFactorisation: (UP, UP) -> Factored UP
+      ++ balancedFactorisation(a, b) returns
+      ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
+      ++ \spad{pi} is balanced with respect to b.
+    balancedFactorisation: (UP, List UP) -> Factored UP
+      ++ balancedFactorisation(a, [b1,...,bn]) returns
+      ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
+      ++ pi is balanced with respect to \spad{[b1,...,bm]}.
+
+  Implementation ==> add
+    balSqfr : (UP, Integer, List UP) -> Factored UP
+    balSqfr1: (UP, Integer,      UP) -> Factored UP
+
+    balancedFactorisation(a:UP, b:UP) == balancedFactorisation(a, [b])
+
+    balSqfr1(a, n, b) ==
+      g := gcd(a, b)
+      fa := sqfrFactor((a exquo g)::UP, n)
+      ground? g => fa
+      fa * balSqfr1(g, n, (b exquo (g ** order(b, g)))::UP)
+
+    balSqfr(a, n, l) ==
+      b := first l
+      empty? rest l => balSqfr1(a, n, b)
+      */[balSqfr1(f.factor, n, b) for f in factors balSqfr(a,n,rest l)]
+
+    balancedFactorisation(a:UP, l:List UP) ==
+      empty?(ll := select(#1 ^= 0, l)) =>
+        error "balancedFactorisation: 2nd argument is empty or all 0"
+      sa := squareFree a
+      unit(sa) * */[balSqfr(f.factor,f.exponent,ll) for f in factors sa])
+
+@
+<<BALFACT.dotabb>>=
+"BALFACT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=BALFACT"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"BALFACT" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package BOP1 BasicOperatorFunctions1}
+\pagehead{BasicOperatorFunctions1}{BOP1}
+\pagepic{ps/v104basicoperatorfunctions1.ps}{BOP1}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package BOP1 BasicOperatorFunctions1>>=
+)abbrev package BOP1 BasicOperatorFunctions1
+++ Tools to set/get common properties of operators
+++ Author: Manuel Bronstein
+++ Date Created: 28 Mar 1988
+++ Date Last Updated: 15 May 1990
+++ Description:
+++   This package exports functions to set some commonly used properties
+++   of operators, including properties which contain functions.
+++ Keywords: operator.
+BasicOperatorFunctions1(A:SetCategory): Exports == Implementation where
+  OP   ==> BasicOperator
+  EVAL    ==> "%eval"
+  CONST   ==> "%constant"
+  DIFF    ==> "%diff"
+
+  Exports ==> with
+    evaluate        : (OP, List A)      -> Union(A, "failed")
+      ++ evaluate(op, [a1,...,an]) checks if op has an "%eval"
+      ++ property f. If it has, then \spad{f(a1,...,an)} is returned, and
+      ++ "failed" otherwise.
+    evaluate        : (OP, List A -> A) -> OP
+      ++ evaluate(op, foo) attaches foo as the "%eval" property
+      ++ of op. If op has an "%eval" property f, then applying op
+      ++ to \spad{(a1,...,an)} returns the result of \spad{f(a1,...,an)}.
+    evaluate        : (OP, A -> A)      -> OP
+      ++ evaluate(op, foo) attaches foo as the "%eval" property
+      ++ of op. If op has an "%eval" property f, then applying op
+      ++ to a returns the result of \spad{f(a)}. Argument op must be unary.
+    evaluate        : OP                -> Union(List A -> A, "failed")
+      ++ evaluate(op) returns the value of the "%eval" property of
+      ++ op if it has one, and "failed" otherwise.
+    derivative      : (OP, List (List A -> A)) -> OP
+      ++ derivative(op, [foo1,...,foon]) attaches [foo1,...,foon] as
+      ++ the "%diff" property of op. If op has an "%diff" property
+      ++ \spad{[f1,...,fn]} then applying a derivation D 
+      ++ to \spad{op(a1,...,an)}
+      ++ returns \spad{f1(a1,...,an) * D(a1) + ... + fn(a1,...,an) * D(an)}.
+    derivative      : (OP, A -> A) -> OP
+      ++ derivative(op, foo) attaches foo as the "%diff" property
+      ++ of op. If op has an "%diff" property f, then applying a
+      ++ derivation D to op(a) returns \spad{f(a) * D(a)}. 
+      ++ Argument op must be unary.
+    derivative      : OP -> Union(List(List A -> A), "failed")
+      ++ derivative(op) returns the value of the "%diff" property of
+      ++ op if it has one, and "failed" otherwise.
+    if A has OrderedSet then
+      constantOperator: A -> OP
+        ++ constantOperator(a) returns a nullary operator op
+        ++ such that \spad{op()} always evaluate to \spad{a}.
+      constantOpIfCan : OP -> Union(A, "failed")
+        ++ constantOpIfCan(op) returns \spad{a} if op is the constant
+        ++ nullary operator always returning \spad{a}, "failed" otherwise.
+
+  Implementation ==> add
+    evaluate(op:OP, func:A -> A) == evaluate(op, func first #1)
+
+    evaluate op ==
+      (func := property(op, EVAL)) case "failed" => "failed"
+      (func::None) pretend (List A -> A)
+
+    evaluate(op:OP, args:List A) ==
+      (func := property(op, EVAL)) case "failed" => "failed"
+      ((func::None) pretend (List A -> A)) args
+
+    evaluate(op:OP, func:List A -> A) ==
+      setProperty(op, EVAL, func pretend None)
+
+    derivative op ==
+      (func := property(op, DIFF)) case "failed" => "failed"
+      ((func::None) pretend List(List A -> A))
+
+    derivative(op:OP, grad:List(List A -> A)) ==
+      setProperty(op, DIFF, grad pretend None)
+
+    derivative(op:OP, f:A -> A) ==
+      unary? op or nary? op =>
+        derivative(op, [f first #1]$List(List A -> A))
+      error "Operator is not unary"
+
+    if A has OrderedSet then
+      cdisp   : (OutputForm, List OutputForm) -> OutputForm
+      csex    : (InputForm,  List InputForm) -> InputForm
+      eqconst?: (OP, OP) -> Boolean
+      ltconst?: (OP, OP) -> Boolean
+      constOp : A -> OP
+
+      opconst:OP :=
+        comparison(equality(operator("constant"::Symbol, 0), eqconst?),
+                                                               ltconst?)
+
+      cdisp(a, l) == a
+      csex(a, l)  == a
+
+      eqconst?(a, b) ==
+        (va := property(a, CONST)) case "failed" => not has?(b, CONST)
+        ((vb := property(b, CONST)) case None) and
+           ((va::None) pretend A) = ((vb::None) pretend A)
+
+      ltconst?(a, b) ==
+        (va := property(a, CONST)) case "failed" => has?(b, CONST)
+        ((vb := property(b, CONST)) case None) and
+           ((va::None) pretend A) < ((vb::None) pretend A)
+
+      constOp a ==
+        setProperty(display(copy opconst, cdisp(a::OutputForm, #1)),
+                                                  CONST, a pretend None)
+
+      constantOpIfCan op ==
+        is?(op, "constant"::Symbol) and
+          ((u := property(op, CONST)) case None) => (u::None) pretend A
+        "failed"
+
+      if A has ConvertibleTo InputForm then
+        constantOperator a == input(constOp a, csex(convert a, #1))
+      else
+        constantOperator a == constOp a
+
+@
+<<BOP1.dotabb>>=
+"BOP1" [color="#FF4488",href="bookvol10.4.pdf#nameddest=BOP1"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"BOP1" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package BEZOUT BezoutMatrix}
 \pagehead{BezoutMatrix}{BEZOUT}
 \pagepic{ps/v104bezoutmatrix.ps}{BEZOUT}{1.00}
@@ -4608,6 +4840,104 @@ BezoutMatrix(R,UP,M,Row,Col): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package BOUNDZRO BoundIntegerRoots}
+\pagehead{BoundIntegerRoots}{BOUNDZRO}
+\pagepic{ps/v104boundintegerroots.ps}{BOUNDZRO}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package BOUNDZRO BoundIntegerRoots>>=
+)abbrev package BOUNDZRO BoundIntegerRoots
+++ Author: Manuel Bronstein
+++ Date Created: 11 March 1991
+++ Date Last Updated: 18 November 1991
+++ Description:
+++   \spadtype{BoundIntegerRoots} provides functions to
+++   find lower bounds on the integer roots of a polynomial.
+BoundIntegerRoots(F, UP): Exports == Implementation where
+  F  : Join(Field, RetractableTo Fraction Integer)
+  UP : UnivariatePolynomialCategory F
+
+  Z   ==> Integer
+  Q   ==> Fraction Z
+  K   ==> Kernel F
+  UPQ ==> SparseUnivariatePolynomial Q
+  ALGOP ==> "%alg"
+
+  Exports ==> with
+    integerBound: UP -> Z
+      ++ integerBound(p) returns a lower bound on the negative integer
+      ++ roots of p, and 0 if p has no negative integer roots.
+
+  Implementation ==> add
+    import RationalFactorize(UPQ)
+    import UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
+
+    qbound : (UP, UPQ) -> Z
+    zroot1 : UP -> Z
+    qzroot1: UPQ -> Z
+    negint : Q -> Z
+
+-- returns 0 if p has no integer root < 0, its negative integer root otherwise
+    qzroot1 p == negint(- leadingCoefficient(reductum p) / leadingCoefficient p)
+
+-- returns 0 if p has no integer root < 0, its negative integer root otherwise
+    zroot1 p ==
+      z := - leadingCoefficient(reductum p) / leadingCoefficient p
+      (r := retractIfCan(z)@Union(Q, "failed")) case Q => negint(r::Q)
+      0
+
+-- returns 0 if r is not a negative integer, r otherwise
+    negint r ==
+      ((u := retractIfCan(r)@Union(Z, "failed")) case Z) and (u::Z < 0) => u::Z
+      0
+
+    if F has ExpressionSpace then
+      bringDown: F -> Q
+
+-- the random substitution used by bringDown is NOT always a ring-homorphism
+-- (because of potential algebraic kernels), but is ALWAYS a Z-linear map.
+-- this guarantees that bringing down the coefficients of (x + n) q(x) for an
+-- integer n yields a polynomial h(x) which is divisible by x + n
+-- the only problem is that evaluating with random numbers can cause a
+-- division by 0. We should really be able to trap this error later and
+-- reevaluate with a new set of random numbers    MB 11/91
+      bringDown f ==
+        t := tower f
+        retract eval(f, t, [random()$Q :: F for k in t])
+
+      integerBound p ==
+--        one? degree p => zroot1 p
+        (degree p) = 1 => zroot1 p
+        q1 := map(bringDown, p)
+        q2 := map(bringDown, p)
+        qbound(p, gcd(q1, q2))
+
+    else
+      integerBound p ==
+--        one? degree p => zroot1 p
+        (degree p) = 1 => zroot1 p
+        qbound(p, map(retract(#1)@Q, p))
+
+-- we can probably do better here (i.e. without factoring)
+    qbound(p, q) ==
+      bound:Z := 0
+      for rec in factors factor q repeat
+--        if one?(degree(rec.factor)) and ((r := qzroot1(rec.factor)) < bound)
+        if ((degree(rec.factor)) = 1) and ((r := qzroot1(rec.factor)) < bound)
+           and zero? p(r::Q::F) then bound := r
+      bound
+
+@
+<<BOUNDZRO.dotabb>>=
+"BOUNDZRO" [color="#FF4488",href="bookvol10.4.pdf#nameddest=BOUNDZRO"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"BOUNDZRO" -> "PFECAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package BRILL BrillhartTests}
 \pagehead{BrillhartTests}{BRILL}
 \pagepic{ps/v104brillharttests.ps}{BRILL}{1.00}
@@ -5799,6 +6129,204 @@ CommonDenominator(R, Q, A): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package COMMONOP CommonOperators}
+\pagehead{CommonOperators}{COMMONOP}
+\pagepic{ps/v104commonoperators.ps}{COMMONOP}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package COMMONOP CommonOperators>>=
+)abbrev package COMMONOP CommonOperators
+++ Provides commonly used operators
+++ Author: Manuel Bronstein
+++ Date Created: 25 Mar 1988
+++ Date Last Updated: 2 December 1994
+++ Description:
+++ This package exports the elementary operators, with some semantics
+++ already attached to them. The semantics that is attached here is not
+++ dependent on the set in which the operators will be applied.
+++ Keywords: operator.
+CommonOperators(): Exports == Implementation where
+  OP  ==> BasicOperator
+  O   ==> OutputForm
+  POWER ==> "%power"::Symbol
+  ALGOP ==> "%alg"
+  EVEN  ==> "even"
+  ODD   ==> "odd"
+  DUMMYVAR ==> "%dummyVar"
+
+  Exports ==> with
+    operator: Symbol -> OP
+        ++ operator(s) returns an operator with name s, with the
+        ++ appropriate semantics if s is known. If s is not known,
+        ++ the result has no semantics.
+
+  Implementation ==> add
+    dpi        : List O -> O
+    dgamma     : List O -> O
+    dquote     : List O -> O
+    dexp       : O -> O
+    dfact      : O -> O
+    startUp    : Boolean -> Void
+    setDummyVar: (OP, NonNegativeInteger) -> OP
+
+    brandNew?:Reference(Boolean) := ref true
+
+    opalg   := operator("rootOf"::Symbol, 2)$OP
+    oproot  := operator("nthRoot"::Symbol, 2)
+    oppi    := operator("pi"::Symbol, 0)
+    oplog   := operator("log"::Symbol, 1)
+    opexp   := operator("exp"::Symbol, 1)
+    opabs   := operator("abs"::Symbol, 1)
+    opsin   := operator("sin"::Symbol, 1)
+    opcos   := operator("cos"::Symbol, 1)
+    optan   := operator("tan"::Symbol, 1)
+    opcot   := operator("cot"::Symbol, 1)
+    opsec   := operator("sec"::Symbol, 1)
+    opcsc   := operator("csc"::Symbol, 1)
+    opasin  := operator("asin"::Symbol, 1)
+    opacos  := operator("acos"::Symbol, 1)
+    opatan  := operator("atan"::Symbol, 1)
+    opacot  := operator("acot"::Symbol, 1)
+    opasec  := operator("asec"::Symbol, 1)
+    opacsc  := operator("acsc"::Symbol, 1)
+    opsinh  := operator("sinh"::Symbol, 1)
+    opcosh  := operator("cosh"::Symbol, 1)
+    optanh  := operator("tanh"::Symbol, 1)
+    opcoth  := operator("coth"::Symbol, 1)
+    opsech  := operator("sech"::Symbol, 1)
+    opcsch  := operator("csch"::Symbol, 1)
+    opasinh := operator("asinh"::Symbol, 1)
+    opacosh := operator("acosh"::Symbol, 1)
+    opatanh := operator("atanh"::Symbol, 1)
+    opacoth := operator("acoth"::Symbol, 1)
+    opasech := operator("asech"::Symbol, 1)
+    opacsch := operator("acsch"::Symbol, 1)
+    opbox   := operator("%box"::Symbol)$OP
+    oppren  := operator("%paren"::Symbol)$OP
+    opquote := operator("applyQuote"::Symbol)$OP
+    opdiff  := operator("%diff"::Symbol, 3)
+    opsi    := operator("Si"::Symbol, 1)
+    opci    := operator("Ci"::Symbol, 1)
+    opei    := operator("Ei"::Symbol, 1)
+    opli    := operator("li"::Symbol, 1)
+    operf   := operator("erf"::Symbol, 1)
+    opli2   := operator("dilog"::Symbol, 1)
+    opGamma     := operator("Gamma"::Symbol, 1)
+    opGamma2    := operator("Gamma2"::Symbol, 2)
+    opBeta      := operator("Beta"::Symbol, 2)
+    opdigamma   := operator("digamma"::Symbol, 1)
+    oppolygamma := operator("polygamma"::Symbol, 2)
+    opBesselJ   := operator("besselJ"::Symbol, 2)
+    opBesselY   := operator("besselY"::Symbol, 2)
+    opBesselI   := operator("besselI"::Symbol, 2)
+    opBesselK   := operator("besselK"::Symbol, 2)
+    opAiryAi    := operator("airyAi"::Symbol,  1)
+    opAiryBi    := operator("airyBi"::Symbol , 1)
+    opint   := operator("integral"::Symbol, 3)
+    opdint  := operator("%defint"::Symbol, 5)
+    opfact  := operator("factorial"::Symbol, 1)
+    opperm  := operator("permutation"::Symbol, 2)
+    opbinom := operator("binomial"::Symbol, 2)
+    oppow   := operator(POWER, 2)
+    opsum   := operator("summation"::Symbol, 3)
+    opdsum  := operator("%defsum"::Symbol, 5)
+    opprod  := operator("product"::Symbol, 3)
+    opdprod := operator("%defprod"::Symbol, 5)
+
+    algop   := [oproot, opalg]$List(OP)
+    rtrigop := [opsin, opcos, optan, opcot, opsec, opcsc,
+                         opasin, opacos, opatan, opacot, opasec, opacsc]
+    htrigop := [opsinh, opcosh, optanh, opcoth, opsech, opcsch,
+                   opasinh, opacosh, opatanh, opacoth, opasech, opacsch]
+    trigop  := concat(rtrigop, htrigop)
+    elemop  := concat(trigop, [oppi, oplog, opexp])
+    primop  := [opei, opli, opsi, opci, operf, opli2, opint, opdint]
+    combop  := [opfact, opperm, opbinom, oppow,
+                                         opsum, opdsum, opprod, opdprod]
+    specop  := [opGamma, opGamma2, opBeta, opdigamma, oppolygamma, opabs,
+                opBesselJ, opBesselY, opBesselI, opBesselK, opAiryAi,
+                 opAiryBi]
+    anyop   := [oppren, opdiff, opbox, opquote]
+    allop   := concat(concat(concat(concat(concat(
+                            algop,elemop),primop),combop),specop),anyop)
+
+-- odd and even operators, must be maintained current!
+    evenop := [opcos, opsec, opcosh, opsech, opabs]
+    oddop  := [opsin, opcsc, optan, opcot, opasin, opacsc, opatan,
+               opsinh, opcsch, optanh, opcoth, opasinh, opacsch,opatanh,opacoth,
+                opsi, operf]
+
+-- operators whose second argument is a dummy variable
+    dummyvarop1 := [opdiff,opalg, opint, opsum, opprod]
+-- operators whose second and third arguments are dummy variables
+    dummyvarop2 := [opdint, opdsum, opdprod]
+
+    operator s ==
+      if (deref brandNew?) then startUp false
+      for op in allop repeat
+        is?(op, s) => return copy op
+      operator(s)$OP
+
+    dpi l    == "%pi"::Symbol::O
+    dfact x  == postfix("!"::Symbol::O, (ATOM(x)$Lisp => x; paren x))
+    dquote l == prefix(quote(first(l)::O), rest l)
+    dgamma l == prefix(hconcat("|"::Symbol::O, overbar(" "::Symbol::O)), l)
+    setDummyVar(op, n) == setProperty(op, DUMMYVAR, n pretend None)
+
+    dexp x ==
+      e := "%e"::Symbol::O
+      x = 1::O => e
+      e ** x
+
+    startUp b ==
+      brandNew?() := b
+      display(oppren, paren)
+      display(opbox, commaSeparate)
+      display(oppi, dpi)
+      display(opexp, dexp)
+      display(opGamma, dgamma)
+      display(opGamma2, dgamma)
+      display(opfact, dfact)
+      display(opquote, dquote)
+      display(opperm, supersub("A"::Symbol::O, #1))
+      display(opbinom, binomial(first #1, second #1))
+      display(oppow, first(#1) ** second(#1))
+      display(opsum,   sum(first #1, second #1, third #1))
+      display(opprod, prod(first #1, second #1, third #1))
+      display(opint, int(first #1 * hconcat("d"::Symbol::O, second #1),
+                                                   empty(), third #1))
+      input(oppren, convert concat(convert("("::Symbol)@InputForm,
+                            concat(#1, convert(")"::Symbol)@InputForm)))
+      input(oppow, convert concat(convert("**"::Symbol)@InputForm, #1))
+      input(oproot,
+            convert [convert("**"::Symbol)@InputForm, first #1, 1 / second #1])
+      for op in algop   repeat assert(op, ALGOP)
+      for op in rtrigop repeat assert(op, "rtrig")
+      for op in htrigop repeat assert(op, "htrig")
+      for op in trigop  repeat assert(op, "trig")
+      for op in elemop  repeat assert(op, "elem")
+      for op in primop  repeat assert(op, "prim")
+      for op in combop  repeat assert(op, "comb")
+      for op in specop  repeat assert(op, "special")
+      for op in anyop   repeat assert(op, "any")
+      for op in evenop  repeat assert(op, EVEN)
+      for op in oddop   repeat assert(op, ODD)
+      for op in dummyvarop1 repeat setDummyVar(op, 1)
+      for op in dummyvarop2 repeat setDummyVar(op, 2)
+      assert(oppren, "linear")
+      void
+
+@
+<<COMMONOP.dotabb>>=
+"COMMONOP" [color="#FF4488",href="bookvol10.4.pdf#nameddest=COMMONOP"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"COMMONOP" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package COMPFACT ComplexFactorization}
 \pagehead{ComplexFactorization}{COMPFACT}
 \pagepic{ps/v104complexfactorization.ps}{COMPFACT}{1.00}
@@ -6916,6 +7444,102 @@ ComplexTrigonometricManipulations(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODECONST ConstantLODE}
+\pagehead{ConstantLODE}{ODECONST}
+\pagepic{ps/v104constantlode.ps}{ODECONST}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODECONST ConstantLODE>>=
+)abbrev package ODECONST ConstantLODE
+++ Author: Manuel Bronstein
+++ Date Created: 18 March 1991
+++ Date Last Updated: 3 February 1994
+++ Description: Solution of linear ordinary differential equations, constant coefficient case.
+ConstantLODE(R, F, L): Exports == Implementation where
+  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+          LinearlyExplicitRingOver Integer, CharacteristicZero)
+  F: Join(AlgebraicallyClosedFunctionSpace R,
+          TranscendentalFunctionCategory, PrimitiveFunctionCategory)
+  L: LinearOrdinaryDifferentialOperatorCategory F
+
+  Z   ==> Integer
+  SY  ==> Symbol
+  K   ==> Kernel F
+  V   ==> Vector F
+  M   ==> Matrix F
+  SUP ==> SparseUnivariatePolynomial F
+
+  Exports ==> with
+    constDsolve: (L, F, SY) -> Record(particular:F, basis:List F)
+      ++ constDsolve(op, g, x) returns \spad{[f, [y1,...,ym]]}
+      ++ where f is a particular solution of the equation \spad{op y = g},
+      ++ and the \spad{yi}'s form a basis for the solutions of \spad{op y = 0}.
+
+  Implementation ==> add
+    import ODETools(F, L)
+    import ODEIntegration(R, F)
+    import ElementaryFunctionSign(R, F)
+    import AlgebraicManipulations(R, F)
+    import FunctionSpaceIntegration(R, F)
+    import FunctionSpaceUnivariatePolynomialFactor(R, F, SUP)
+
+    homoBasis: (L, F) -> List F
+    quadSol  : (SUP, F) -> List F
+    basisSqfr: (SUP, F) -> List F
+    basisSol : (SUP, Z, F) -> List F
+
+    constDsolve(op, g, x) ==
+      b := homoBasis(op, x::F)
+      [particularSolution(op, g, b, int(#1, x))::F, b]
+
+    homoBasis(op, x) ==
+      p:SUP := 0
+      while op ^= 0 repeat
+          p  := p + monomial(leadingCoefficient op, degree op)
+          op := reductum op
+      b:List(F) := empty()
+      for ff in factors ffactor p repeat
+        b := concat_!(b, basisSol(ff.factor, dec(ff.exponent), x))
+      b
+
+    basisSol(p, n, x) ==
+      l := basisSqfr(p, x)
+      zero? n => l
+      ll := copy l
+      xn := x::F
+      for i in 1..n repeat
+        l := concat_!(l, [xn * f for f in ll])
+        xn := x * xn
+      l
+
+    basisSqfr(p, x) ==
+--      one?(d := degree p) =>
+      ((d := degree p) = 1) =>
+        [exp(- coefficient(p, 0) * x / leadingCoefficient p)]
+      d = 2 => quadSol(p, x)
+      [exp(a * x) for a in rootsOf p]
+
+    quadSol(p, x) ==
+      (u := sign(delta := (b := coefficient(p, 1))**2 - 4 *
+        (a := leadingCoefficient p) * (c := coefficient(p, 0))))
+          case Z and negative?(u::Z) =>
+            y := x / (2 * a)
+            r := - b * y
+            i := rootSimp(sqrt(-delta)) * y
+            [exp(r) * cos(i), exp(r) * sin(i)]
+      [exp(a * x) for a in zerosOf p]
+
+@
+<<ODECONST.dotabb>>=
+"ODECONST" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODECONST"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"ODECONST" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package COORDSYS CoordinateSystems}
 \pagehead{CoordinateSystems}{COORDSYS}
 \pagepic{ps/v104coordinatesystems.ps}{COORDSYS}{1.00}
@@ -8844,6 +9468,138 @@ DiscreteLogarithmPackage(M): public == private where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package DISPLAY DisplayPackage}
+\pagehead{DisplayPackage}{DISPLAY}
+\pagepic{ps/v104displaypackage.ps}{DISPLAY}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package DISPLAY DisplayPackage>>=
+)abbrev package DISPLAY DisplayPackage
+++ Author: Robert S. Sutor
+++ Date Created: September 1986
+++ Date Last Updated:
+++ Basic Operations: bright, newLine, copies, center, say, sayLength
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: DisplayPackage allows one to print strings in a nice manner,
+++ including highlighting substrings.
+
+DisplayPackage: public == private where
+  I       ==> Integer
+  L       ==> List
+  S       ==> String
+  RECLR   ==> Record(lhs : S, rhs : S)
+
+  public  == with
+    bright:       S           -> L S
+      ++ bright(s) sets the font property of the string s to bold-face type.
+    bright:       L S         -> L S
+      ++ bright(l) sets the font property of a list of strings, l, to
+      ++ bold-face type.
+    newLine:      ()          -> S
+      ++ newLine() sends a new line command to output.
+
+    copies:       (I,S)       -> S
+      ++ copies(i,s) will take a string s and create a new string composed of
+      ++ i copies of s.
+    center:       (S,I,S)     -> S
+      ++ center(s,i,s) takes the first string s, and centers it within a string
+      ++ of length i, in which the other elements of the string are composed
+      ++ of as many replications as possible of the second indicated string, s
+      ++ which must have a length greater than that of an empty string.
+    center:       (L S,I,S)   -> L S
+      ++ center(l,i,s) takes a list of strings l, and centers them within a
+      ++ list of strings which is i characters long, in which the remaining
+      ++ spaces are filled with strings composed of as many repetitions as
+      ++ possible of the last string parameter s.
+
+    say:          S           -> Void
+      ++ say(s) sends a string s to output.
+    say:          L S         -> Void
+      ++ say(l) sends a list of strings l to output.
+    sayLength:    S           -> I
+      ++ sayLength(s) returns the length of a string s as an integer.
+    sayLength:    L S         -> I
+      ++ sayLength(l) returns the length of a list of strings l as an integer.
+
+  private == add
+    --StringManipulations()
+
+    center0:  (I,I,S) -> RECLR
+
+    s : S
+    l : L S
+
+    HION    : S := "%b"
+    HIOFF   : S := "%d"
+    NEWLINE : S := "%l"
+
+    bright s == [HION,s,HIOFF]$(L S)
+    bright l == cons(HION,append(l,list HIOFF))
+    newLine() == NEWLINE
+
+    copies(n : I, s : S) ==
+      n < 1 => ""
+      n = 1 => s
+      t : S := copies(n quo 2, s)
+      odd? n => concat [s,t,t]
+      concat [t,t]
+
+    center0(len : I, wid : I, fill : S) : RECLR ==
+      (wid < 1) or (len >= wid) => ["",""]$RECLR
+      m : I := (wid - len) quo 2
+      t : S := copies(1 + (m quo (sayLength fill)),fill)
+      [t(1..m),t(1..wid-len-m)]$RECLR
+
+    center(s, wid, fill) ==
+      wid < 1 => ""
+      len : I := sayLength s
+      len = wid => s
+      len > wid => s(1..wid)
+      rec : RECLR := center0(len,wid,fill)
+      concat [rec.lhs,s,rec.rhs]
+
+    center(l, wid, fill) ==
+      wid < 1 => [""]$(L S)
+      len : I := sayLength l
+      len = wid => l
+--    len > wid => s(1..wid)
+      rec : RECLR := center0(len,wid,fill)
+      cons(rec.lhs,append(l,list rec.rhs))
+
+    say s ==
+      sayBrightly$Lisp s
+      void()$Void
+
+    say l ==
+      sayBrightly$Lisp l
+      void()$Void
+
+    sayLength s == #s
+
+    sayLength l ==
+      sum : I := 0
+      for s in l repeat
+        s = HION      => sum := sum + 1
+        s = HIOFF     => sum := sum + 1
+        s = NEWLINE   => sum
+        sum := sum + sayLength s
+      sum
+
+@
+<<DISPLAY.dotabb>>=
+"DISPLAY" [color="#FF4488",href="bookvol10.4.pdf#nameddest=DISPLAY"]
+"STRING" [color="#88FF44",href="bookvol10.3.pdf#nameddest=STRING"]
+"DISPLAY" -> "STRING"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package DDFACT DistinctDegreeFactorize}
 \pagehead{DistinctDegreeFactorize}{DDFACT}
 \pagepic{ps/v104distinctdegreefactorize.ps}{DDFACT}{1.00}
@@ -11966,6 +12722,552 @@ ElementaryFunctionDefiniteIntegration(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package LODEEF ElementaryFunctionLODESolver}
+\pagehead{ElementaryFunctionLODESolver}{LODEEF}
+\pagepic{ps/v104elementaryfunctionlodesolver.ps}{LODEEF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package LODEEF ElementaryFunctionLODESolver>>=
+)abbrev package LODEEF ElementaryFunctionLODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 3 February 1994
+++ Date Last Updated: 9 March 1994
+++ Description:
+++ \spad{ElementaryFunctionLODESolver} provides the top-level
+++ functions for finding closed form solutions of linear ordinary
+++ differential equations and initial value problems.
+++ Keywords: differential equation, ODE
+ElementaryFunctionLODESolver(R, F, L): Exports == Implementation where
+  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+          LinearlyExplicitRingOver Integer, CharacteristicZero)
+  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+          PrimitiveFunctionCategory)
+  L: LinearOrdinaryDifferentialOperatorCategory F
+
+  SY  ==> Symbol
+  N   ==> NonNegativeInteger
+  K   ==> Kernel F
+  V   ==> Vector F
+  M   ==> Matrix F
+  UP  ==> SparseUnivariatePolynomial F
+  RF  ==> Fraction UP
+  UPUP==> SparseUnivariatePolynomial RF
+  P   ==> SparseMultivariatePolynomial(R, K)
+  P2  ==> SparseMultivariatePolynomial(P, K)
+  LQ  ==> LinearOrdinaryDifferentialOperator1 RF
+  REC ==> Record(particular: F, basis: List F)
+  U   ==> Union(REC, "failed")
+  ALGOP  ==> "%alg"
+
+  Exports ==> with
+    solve: (L, F, SY) -> U
+      ++ solve(op, g, x) returns either a solution of the ordinary differential
+      ++ equation \spad{op y = g} or "failed" if no non-trivial solution can be
+      ++ found; When found, the solution is returned in the form
+      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
+      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+      ++ associated homogenuous equation \spad{op y = 0}.
+      ++ A full basis for the solutions of the homogenuous equation
+      ++ is not always returned, only the solutions which were found;
+      ++ \spad{x} is the dependent variable.
+    solve: (L, F, SY, F, List F) -> Union(F, "failed")
+      ++ solve(op, g, x, a, [y0,...,ym]) returns either the solution
+      ++ of the initial value problem \spad{op y = g, y(a) = y0, y'(a) = y1,...}
+      ++ or "failed" if the solution cannot be found;
+      ++ \spad{x} is the dependent variable.
+
+  Implementation ==> add
+    import Kovacic(F, UP)
+    import ODETools(F, L)
+    import RationalLODE(F, UP)
+    import RationalRicDE(F, UP)
+    import ODEIntegration(R, F)
+    import ConstantLODE(R, F, L)
+    import IntegrationTools(R, F)
+    import ReductionOfOrder(F, L)
+    import ReductionOfOrder(RF, LQ)
+    import PureAlgebraicIntegration(R, F, L)
+    import FunctionSpacePrimitiveElement(R, F)
+    import LinearSystemMatrixPackage(F, V, V, M)
+    import SparseUnivariatePolynomialFunctions2(RF, F)
+    import FunctionSpaceUnivariatePolynomialFactor(R, F, UP)
+    import LinearOrdinaryDifferentialOperatorFactorizer(F, UP)
+    import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+                                                             K, R, P, F)
+
+    upmp       : (P, List K) -> P2
+    downmp     : (P2, List K, List P) -> P
+    xpart      : (F, SY) -> F
+    smpxpart   : (P, SY, List K, List P) -> P
+    multint    : (F, List F, SY) -> F
+    ulodo      : (L, K) -> LQ
+    firstOrder : (F, F, F, SY) -> REC
+    rfSolve    : (L, F, K, SY) -> U
+    ratlogsol  : (LQ, List RF, K, SY) -> List F
+    expsols    : (LQ, K, SY) -> List F
+    homosolve  : (L, LQ, List RF, K, SY) -> List F
+    homosolve1 : (L, List F, K, SY) -> List F
+    norf1      : (L, K, SY, N) -> List F
+    kovode     : (LQ, K, SY) -> List F
+    doVarParams: (L, F, List F, SY) -> U
+    localmap   : (F -> F, L) -> L
+    algSolve   : (L, F, K, List K, SY) -> U
+    palgSolve  : (L, F, K, K, SY) -> U
+    lastChance : (L, F, SY) -> U
+
+    diff := D()$L
+
+    smpxpart(p, x, l, lp) == downmp(primitivePart upmp(p, l), l, lp)
+    downmp(p, l, lp)      == ground eval(p, l, lp)
+    homosolve(lf, op, sols, k, x) == homosolve1(lf, ratlogsol(op,sols,k,x),k,x)
+
+-- left hand side has algebraic (not necessarily pure) coefficients
+    algSolve(op, g, k, l, x) ==
+      symbolIfCan(kx := ksec(k, l, x)) case SY => palgSolve(op, g, kx, k, x)
+      has?(operator kx, ALGOP) =>
+        rec := primitiveElement(kx::F, k::F)
+        z   := rootOf(rec.prim)
+        lk:List K := [kx, k]
+        lv:List F := [(rec.pol1) z, (rec.pol2) z]
+        (u := solve(localmap(eval(#1, lk, lv), op), eval(g, lk, lv), x))
+            case "failed" => "failed"
+        rc := u::REC
+        kz := retract(z)@K
+        [eval(rc.particular, kz, rec.primelt),
+            [eval(f, kz, rec.primelt) for f in rc.basis]]
+      lastChance(op, g, x)
+
+    doVarParams(eq, g, bas, x) ==
+      (u := particularSolution(eq, g, bas, int(#1, x))) case "failed" =>
+         lastChance(eq, g, x)
+      [u::F, bas]
+
+    lastChance(op, g, x) ==
+--      one? degree op => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
+      (degree op) = 1 => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
+      "failed"
+
+-- solves a0 y + a1 y' = g
+-- does not check whether there is a solution in the field generated by
+-- a0, a1 and g
+    firstOrder(a0, a1, g, x) ==
+      h := xpart(expint(- a0 / a1, x), x)
+      [h * int((g / h) / a1, x), [h]]
+
+-- xpart(f,x) removes any constant not involving x from f
+    xpart(f, x) ==
+      l  := reverse_! varselect(tower f, x)
+      lp := [k::P for k in l]
+      smpxpart(numer f, x, l, lp) / smpxpart(denom f, x, l, lp)
+
+    upmp(p, l) ==
+      empty? l => p::P2
+      up := univariate(p, k := first l)
+      l := rest l
+      ans:P2 := 0
+      while up ^= 0 repeat
+        ans := ans + monomial(upmp(leadingCoefficient up, l), k, degree up)
+        up  := reductum up
+      ans
+
+-- multint(a, [g1,...,gk], x) returns gk \int(g(k-1) \int(....g1 \int(a))...)
+    multint(a, l, x) ==
+       for g in l repeat a := g * xpart(int(a, x), x)
+       a
+
+    expsols(op, k, x) ==
+--      one? degree op =>
+      (degree op) = 1 =>
+          firstOrder(multivariate(coefficient(op, 0), k),
+                     multivariate(leadingCoefficient op, k), 0, x).basis
+      [xpart(expint(multivariate(h, k), x), x) for h in ricDsolve(op, ffactor)]
+
+-- Finds solutions with rational logarithmic derivative
+    ratlogsol(oper, sols, k, x) ==
+      bas := [xpart(multivariate(h, k), x) for h in sols]
+      degree(oper) = #bas => bas            -- all solutions are found already
+      rec := ReduceOrder(oper, sols)
+      le := expsols(rec.eq, k, x)
+      int:List(F) := [xpart(multivariate(h, k), x) for h in rec.op]
+      concat_!([xpart(multivariate(h, k), x) for h in sols],
+               [multint(e, int, x) for e in le])
+
+    homosolve1(oper, sols, k, x) ==
+      zero?(n := (degree(oper) - #sols)::N) => sols   -- all solutions found
+      rec := ReduceOrder(oper, sols)
+      int:List(F) := [xpart(h, x) for h in rec.op]
+      concat_!(sols, [multint(e, int, x) for e in norf1(rec.eq, k, x, n::N)])
+
+-- if the coefficients are rational functions, then the equation does not
+-- not have a proper 1st-order right factor over the rational functions
+    norf1(op, k, x, n) ==
+--      one? n => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
+      (n = 1) => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
+-- for order > 2, we check that the coeffs are still rational functions
+      symbolIfCan(kmax vark(coefficients op, x)) case SY =>
+        eq := ulodo(op, k)
+        n = 2 => kovode(eq, k, x)
+        eq := last factor1 eq        -- eq cannot have order 1
+        degree(eq) = 2 =>
+          empty?(bas := kovode(eq, k, x)) => empty()
+          homosolve1(op, bas, k, x)
+        empty()
+      empty()
+
+    kovode(op, k, x) ==
+      b := coefficient(op, 1)
+      a := coefficient(op, 2)
+      (u := kovacic(coefficient(op, 0), b, a, ffactor)) case "failed" => empty()
+      p := map(multivariate(#1, k), u::UPUP)
+      ba := multivariate(- b / a, k)
+-- if p has degree 2 (case 2), then it must be squarefree since the
+-- ode is irreducible over the rational functions, so the 2 roots of p
+-- are distinct and must yield 2 independent solutions.
+      degree(p) = 2 => [xpart(expint(ba/(2::F) + e, x), x) for e in zerosOf p]
+-- otherwise take 1 root of p and find the 2nd solution by reduction of order
+      y1 := xpart(expint(ba / (2::F) + zeroOf p, x), x)
+      [y1, y1 * xpart(int(expint(ba, x) / y1**2, x), x)]
+
+    solve(op:L, g:F, x:SY) ==
+      empty?(l := vark(coefficients op, x)) => constDsolve(op, g, x)
+      symbolIfCan(k := kmax l) case SY => rfSolve(op, g, k, x)
+      has?(operator k, ALGOP) => algSolve(op, g, k, l, x)
+      lastChance(op, g, x)
+
+    ulodo(eq, k) ==
+        op:LQ := 0
+        while eq ^= 0 repeat
+            op := op + monomial(univariate(leadingCoefficient eq, k), degree eq)
+            eq := reductum eq
+        op
+
+-- left hand side has rational coefficients
+    rfSolve(eq, g, k, x) ==
+      op := ulodo(eq, k)
+      empty? remove_!(k, varselect(kernels g, x)) =>  -- i.e. rhs is rational
+        rc := ratDsolve(op, univariate(g, k))
+        rc.particular case "failed" =>                -- this implies g ^= 0
+          doVarParams(eq, g, homosolve(eq, op, rc.basis, k, x), x)
+        [multivariate(rc.particular::RF, k), homosolve(eq, op, rc.basis, k, x)]
+      doVarParams(eq, g, homosolve(eq, op, ratDsolve(op, 0).basis, k, x), x)
+
+    solve(op, g, x, a, y0) ==
+      (u := solve(op, g, x)) case "failed" => "failed"
+      hp := h := (u::REC).particular
+      b := (u::REC).basis
+      v:V := new(n := #y0, 0)
+      kx:K := kernel x
+      for i in minIndex v .. maxIndex v for yy in y0 repeat
+        v.i := yy - eval(h, kx, a)
+        h := diff h
+      (sol := particularSolution(map_!(eval(#1,kx,a),wronskianMatrix(b,n)), v))
+         case "failed" => "failed"
+      for f in b for i in minIndex(s := sol::V) .. repeat
+        hp := hp + s.i * f
+      hp
+
+    localmap(f, op) ==
+        ans:L := 0
+        while op ^= 0 repeat
+            ans := ans + monomial(f leadingCoefficient op, degree op)
+            op  := reductum op
+        ans
+
+-- left hand side has pure algebraic coefficients
+    palgSolve(op, g, kx, k, x) ==
+      rec := palgLODE(op, g, kx, k, x)   -- finds solutions in the coef. field
+      rec.particular case "failed" =>
+        doVarParams(op, g, homosolve1(op, rec.basis, k, x), x)
+      [(rec.particular)::F, homosolve1(op, rec.basis, k, x)]
+
+@
+<<LODEEF.dotabb>>=
+"LODEEF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=LODEEF"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"LODEEF" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODEEF ElementaryFunctionODESolver}
+\pagehead{ElementaryFunctionODESolver}{ODEEF}
+\pagepic{ps/v104elementaryfunctionodesolver.ps}{ODEEF}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODEEF ElementaryFunctionODESolver>>=
+)abbrev package ODEEF ElementaryFunctionODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 18 March 1991
+++ Date Last Updated: 8 March 1994
+++ Description:
+++ \spad{ElementaryFunctionODESolver} provides the top-level
+++ functions for finding closed form solutions of ordinary
+++ differential equations and initial value problems.
+++ Keywords: differential equation, ODE
+ElementaryFunctionODESolver(R, F): Exports == Implementation where
+  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+          LinearlyExplicitRingOver Integer, CharacteristicZero)
+  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+          PrimitiveFunctionCategory)
+
+  N   ==> NonNegativeInteger
+  OP  ==> BasicOperator
+  SY  ==> Symbol
+  K   ==> Kernel F
+  EQ  ==> Equation F
+  V   ==> Vector F
+  M   ==> Matrix F
+  UP  ==> SparseUnivariatePolynomial F
+  P   ==> SparseMultivariatePolynomial(R, K)
+  LEQ ==> Record(left:UP, right:F)
+  NLQ ==> Record(dx:F, dy:F)
+  REC ==> Record(particular: F, basis: List F)
+  VEC ==> Record(particular: V, basis: List V)
+  ROW ==> Record(index: Integer, row: V, rh: F)
+  SYS ==> Record(mat:M, vec: V)
+  U   ==> Union(REC, F, "failed")
+  UU  ==> Union(F, "failed")
+  OPDIFF ==> "%diff"::SY
+
+  Exports ==> with
+    solve: (M, V, SY) -> Union(VEC, "failed")
+      ++ solve(m, v, x) returns \spad{[v_p, [v_1,...,v_m]]} such that
+      ++ the solutions of the system \spad{D y = m y + v} are
+      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+      ++ constants, and the \spad{v_i's} form a basis for the solutions of
+      ++ \spad{D y = m y}.
+      ++ \spad{x} is the dependent variable.
+    solve: (M, SY) -> Union(List V, "failed")
+      ++ solve(m, x) returns a basis for the solutions of \spad{D y = m y}.
+      ++ \spad{x} is the dependent variable.
+    solve: (List EQ, List OP, SY) -> Union(VEC, "failed")
+      ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
+      ++ or, if the equations form a fist order linear system, a solution
+      ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
+      ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
+      ++ solutions of the associated homogenuous system.
+      ++ error if the equations do not form a first order linear system
+    solve: (List F, List OP, SY) -> Union(VEC, "failed")
+      ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
+      ++ or, if the equations form a fist order linear system, a solution
+      ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
+      ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
+      ++ solutions of the associated homogenuous system.
+      ++ error if the equations do not form a first order linear system
+    solve: (EQ, OP, SY) -> U
+      ++ solve(eq, y, x) returns either a solution of the ordinary differential
+      ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
+      ++ If the equation is linear ordinary, a solution is of the form
+      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution
+      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+      ++ associated homogenuous equation \spad{f(x,y) = 0};
+      ++ A full basis for the solutions of the homogenuous equation
+      ++ is not always returned, only the solutions which were found;
+      ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
+      ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
+      ++ of the equation for any constant \spad{c};
+      ++ error if the equation is not one of those 2 forms;
+    solve: (F, OP, SY) -> U
+      ++ solve(eq, y, x) returns either a solution of the ordinary differential
+      ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
+      ++ If the equation is linear ordinary, a solution is of the form
+      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
+      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+      ++ associated homogenuous equation \spad{f(x,y) = 0};
+      ++ A full basis for the solutions of the homogenuous equation
+      ++ is not always returned, only the solutions which were found;
+      ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
+      ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
+      ++ of the equation for any constant \spad{c};
+    solve: (EQ, OP, EQ, List F) -> UU
+      ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
+      ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
+      ++ or "failed" if the solution cannot be found;
+      ++ error if the equation is not one linear ordinary or of the form
+      ++ \spad{dy/dx = f(x,y)};
+    solve: (F, OP, EQ, List F) -> UU
+      ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
+      ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
+      ++ or "failed" if the solution cannot be found;
+      ++ error if the equation is not one linear ordinary or of the form
+      ++ \spad{dy/dx = f(x,y)};
+
+  Implementation ==> add
+    import ODEIntegration(R, F)
+    import IntegrationTools(R, F)
+    import NonLinearFirstOrderODESolver(R, F)
+
+    getfreelincoeff : (F, K, SY) -> F
+    getfreelincoeff1: (F, K, List F) -> F
+    getlincoeff     : (F, K) -> F
+    getcoeff        : (F, K) -> UU
+    parseODE        : (F, OP, SY) -> Union(LEQ, NLQ)
+    parseLODE       : (F, List K, UP, SY) -> LEQ
+    parseSYS        : (List F, List OP, SY) -> Union(SYS, "failed")
+    parseSYSeq      : (F, List K, List K, List F, SY) -> Union(ROW, "failed")
+
+    solve(diffeq:EQ, y:OP, x:SY) == solve(lhs diffeq - rhs diffeq, y, x)
+
+    solve(leq: List EQ, lop: List OP, x:SY) ==
+        solve([lhs eq - rhs eq for eq in leq], lop, x)
+
+    solve(diffeq:EQ, y:OP, center:EQ, y0:List F) ==
+      solve(lhs diffeq - rhs diffeq, y, center, y0)
+
+    solve(m:M, x:SY) ==
+        (u := solve(m, new(nrows m, 0), x)) case "failed" => "failed"
+        u.basis
+
+    solve(m:M, v:V, x:SY) ==
+        Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+        uu := solve(m, v, solve(#1, #2,
+               x)$ElementaryFunctionLODESolver(R, F, Lx))$SystemODESolver(F, Lx)
+        uu case "failed" => "failed"
+        rec := uu::Record(particular: V, basis: M)
+        [rec.particular, [column(rec.basis, i) for i in 1..ncols(rec.basis)]]
+
+    solve(diffeq:F, y:OP, center:EQ, y0:List F) ==
+      a := rhs center
+      kx:K := kernel(x := retract(lhs(center))@SY)
+      (ur := parseODE(diffeq, y, x)) case NLQ =>
+--        not one?(#y0) => error "solve: more than one initial condition!"
+        not ((#y0) = 1) => error "solve: more than one initial condition!"
+        rc := ur::NLQ
+        (u := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
+        u::F - eval(u::F,  [kx, retract(y(x::F))@K], [a, first y0])
+      rec := ur::LEQ
+      p := rec.left
+      Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+      op:Lx := 0
+      while p ^= 0 repeat
+        op := op + monomial(leadingCoefficient p, degree p)
+        p  := reductum p
+      solve(op, rec.right, x, a, y0)$ElementaryFunctionLODESolver(R, F, Lx)
+
+    solve(leq: List F, lop: List OP, x:SY) ==
+        (u := parseSYS(leq, lop, x)) case SYS =>
+            rec := u::SYS
+            solve(rec.mat, rec.vec, x)
+        error "solve: not a first order linear system"
+
+    solve(diffeq:F, y:OP, x:SY) ==
+      (u := parseODE(diffeq, y, x)) case NLQ =>
+        rc := u::NLQ
+        (uu := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
+        uu::F
+      rec := u::LEQ
+      p := rec.left
+      Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+      op:Lx := 0
+      while p ^= 0 repeat
+        op := op + monomial(leadingCoefficient p, degree p)
+        p  := reductum p
+      (uuu := solve(op, rec.right, x)$ElementaryFunctionLODESolver(R, F, Lx))
+         case "failed" => "failed"
+      uuu::REC
+
+-- returns [M, v] s.t. the equations are D x = M x + v
+    parseSYS(eqs, ly, x) ==
+      (n := #eqs) ^= #ly => "failed"
+      m:M := new(n, n, 0)
+      v:V := new(n, 0)
+      xx := x::F
+      lf := [y xx for y in ly]
+      lk0:List(K) := [retract(f)@K for f in lf]
+      lk1:List(K) := [retract(differentiate(f, x))@K for f in lf]
+      for eq in eqs repeat
+          (u := parseSYSeq(eq,lk0,lk1,lf,x)) case "failed" => return "failed"
+          rec := u::ROW
+          setRow_!(m, rec.index, rec.row)
+          v(rec.index) := rec.rh
+      [m, v]
+
+    parseSYSeq(eq, l0, l1, lf, x) ==
+      l := [k for k in varselect(kernels eq, x) | is?(k, OPDIFF)]
+      empty? l or not empty? rest l or zero?(n := position(k := first l,l1)) =>
+         "failed"
+      c := getfreelincoeff1(eq, k, lf)
+      eq := eq - c * k::F
+      v:V := new(#l0, 0)
+      for y in l0 for i in 1.. repeat
+          ci := getfreelincoeff1(eq, y, lf)
+          v.i := - ci / c
+          eq := eq - ci * y::F
+      [n, v, -eq]
+
+-- returns either [p, g] where the equation (diffeq) is of the form p(D)(y) = g
+-- or [p, q] such that the equation (diffeq) is of the form p dx + q dy = 0
+    parseODE(diffeq, y, x) ==
+      f := y(x::F)
+      l:List(K) := [retract(f)@K]
+      n:N := 2
+      for k in varselect(kernels diffeq, x) | is?(k, OPDIFF) repeat
+        if (m := height k) > n then n := m
+      n := (n - 2)::N
+-- build a list of kernels in the order [y^(n)(x),...,y''(x),y'(x),y(x)]
+      for i in 1..n repeat
+        l := concat(retract(f := differentiate(f, x))@K, l)
+      k:K   -- #$^#& compiler requires this line and the next one too...
+      c:F
+      while not(empty? l) and zero?(c := getlincoeff(diffeq, k := first l))
+        repeat l := rest l
+      empty? l or empty? rest l => error "parseODE: equation has order 0"
+      diffeq := diffeq - c * (k::F)
+      ny := name y
+      l := rest l
+      height(k) > 3 => parseLODE(diffeq, l, monomial(c, #l), ny)
+      (u := getcoeff(diffeq, k := first l)) case "failed" => [diffeq, c]
+      eqrhs := (d := u::F) * (k::F) - diffeq
+      freeOf?(eqrhs, ny) and freeOf?(c, ny) and freeOf?(d, ny) =>
+        [monomial(c, 1) + d::UP, eqrhs]
+      [diffeq, c]
+
+-- returns [p, g] where the equation (diffeq) is of the form p(D)(y) = g
+    parseLODE(diffeq, l, p, y) ==
+      not freeOf?(leadingCoefficient p, y) =>
+        error "parseLODE: not a linear ordinary differential equation"
+      d := degree(p)::Integer - 1
+      for k in l repeat
+        p := p + monomial(c := getfreelincoeff(diffeq, k, y), d::N)
+        d := d - 1
+        diffeq := diffeq - c * (k::F)
+      freeOf?(diffeq, y) => [p, - diffeq]
+      error "parseLODE: not a linear ordinary differential equation"
+
+    getfreelincoeff(f, k, y) ==
+      freeOf?(c := getlincoeff(f, k), y) => c
+      error "getfreelincoeff: not a linear ordinary differential equation"
+
+    getfreelincoeff1(f, k, ly) ==
+      c := getlincoeff(f, k)
+      for y in ly repeat
+         not freeOf?(c, y) =>
+            error "getfreelincoeff: not a linear ordinary differential equation"
+      c
+
+    getlincoeff(f, k) ==
+      (u := getcoeff(f, k)) case "failed" =>
+        error "getlincoeff: not an appropriate ordinary differential equation"
+      u::F
+
+    getcoeff(f, k) ==
+      (r := retractIfCan(univariate(denom f, k))@Union(P, "failed"))
+        case "failed" or degree(p := univariate(numer f, k)) > 1 => "failed"
+      coefficient(p, 1) / (r::P)
+
+@
+<<ODEEF.dotabb>>=
+"ODEEF" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODEEF"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"ODEEF" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package SIGNEF ElementaryFunctionSign}
 \pagehead{ElementaryFunctionSign}{SIGNEF}
 \pagepic{ps/v104elementaryfunctionsign.ps}{SIGNEF}{1.00}
@@ -16204,6 +17506,297 @@ ExpressionSpaceODESolver(R, F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OMEXPR ExpressionToOpenMath}
+\pagehead{ExpressionToOpenMath}{OMEXPR}
+\pagepic{ps/v104expressiontoopenmath.ps}{OMEXPR}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OMEXPR ExpressionToOpenMath>>=
+)abbrev package OMEXPR ExpressionToOpenMath
+++ Author: Mike Dewar & Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{ExpressionToOpenMath} provides support for
+++ converting objects of type \spadtype{Expression} into OpenMath.
+ExpressionToOpenMath(R: Join(OpenMath, OrderedSet, Ring)): with
+  OMwrite  : Expression R -> String
+  OMwrite  : (Expression R, Boolean) -> String
+  OMwrite  : (OpenMathDevice, Expression R) -> Void
+  OMwrite  : (OpenMathDevice, Expression R, Boolean) -> Void
+ == add
+  import Expression R
+  SymInfo ==> Record(cd:String, name:String)
+  import SymInfo
+  import Record(key: Symbol, entry: SymInfo)
+  import AssociationList(Symbol, SymInfo)
+  import OMENC
+
+  ----------------------------
+  -- Local translation tables.
+  ----------------------------
+
+  nullaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
+    [pi, ["nums1", "pi"]] ]
+
+  unaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
+    [exp,  ["transc1", "exp"]],_
+    [log,  ["transc1", "ln"]],_
+    [sin,  ["transc1", "sin"]],_
+    [cos,  ["transc1", "cos"]],_
+    [tan,  ["transc1", "tan"]],_
+    [cot,  ["transc1", "cot"]],_
+    [sec,  ["transc1", "sec"]],_
+    [csc,  ["transc1", "csc"]],_
+    [asin, ["transc1", "arcsin"]],_
+    [acos, ["transc1", "arccos"]],_
+    [atan, ["transc1", "arctan"]],_
+    [acot, ["transc1", "arccot"]],_
+    [asec, ["transc1", "arcsec"]],_
+    [acsc, ["transc1", "arccsc"]],_
+    [sinh, ["transc1", "sinh"]],_
+    [cosh, ["transc1", "cosh"]],_
+    [tanh, ["transc1", "tanh"]],_
+    [coth, ["transc1", "coth"]],_
+    [sech, ["transc1", "sech"]],_
+    [csch, ["transc1", "csch"]],_
+    [asinh, ["transc1", "arcsinh"]],_
+    [acosh, ["transc1", "arccosh"]],_
+    [atanh, ["transc1", "arctanh"]],_
+    [acoth, ["transc1", "arccoth"]],_
+    [asech, ["transc1", "arcsech"]],_
+    [acsch, ["transc1", "arccsch"]],_
+    [factorial, ["integer1", "factorial"]],_
+    [abs, ["arith1", "abs"]] ]
+
+    -- Still need the following unary functions:
+    --  digamma
+    --  Gamma
+    --  airyAi
+    --  airyBi
+    --  erf
+    --  Ei
+    --  Si
+    --  Ci
+    --  li
+    --  dilog
+
+    -- Still need the following binary functions:
+    --      Gamma(a, x)
+    --      Beta(x,y) 
+    --      polygamma(k,x)
+    --      besselJ(v,x)
+    --      besselY(v,x)
+    --      besselI(v,x)
+    --      besselK(v,x)
+    --      permutation(n, m)
+    --      summation(x:%, n:Symbol) : as opposed to "definite" sum
+    --      product(x:%, n:Symbol)   : ditto
+
+  ------------------------
+  -- Forward declarations.
+  ------------------------
+
+  outputOMExpr  : (OpenMathDevice, Expression R) -> Void
+
+  -------------------------
+  -- Local helper functions
+  -------------------------
+
+  outputOMArith1(dev: OpenMathDevice, sym: String, args: List Expression R): Void ==
+    OMputApp(dev)
+    OMputSymbol(dev, "arith1", sym)
+    for arg in args repeat
+      OMwrite(dev, arg, false)
+    OMputEndApp(dev)
+
+  outputOMLambda(dev: OpenMathDevice, ex: Expression R, var: Expression R): Void ==
+    OMputBind(dev)
+    OMputSymbol(dev, "fns1", "lambda")
+    OMputBVar(dev)
+    OMwrite(dev, var, false)
+    OMputEndBVar(dev)
+    OMwrite(dev, ex, false)
+    OMputEndBind(dev)
+
+  outputOMInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
+    OMputApp(dev)
+    OMputSymbol(dev, "interval1", "interval")
+    OMwrite(dev, lo, false)
+    OMwrite(dev, hi, false)
+    OMputEndApp(dev)
+
+  outputOMIntInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
+    OMputApp(dev)
+    OMputSymbol(dev, "interval1", "integer__interval")
+    OMwrite(dev, lo, false)
+    OMwrite(dev, hi, false)
+    OMputEndApp(dev)
+
+  outputOMBinomial(dev: OpenMathDevice, args: List Expression R): Void ==
+    not #args=2 => error "Wrong number of arguments to binomial"
+    OMputApp(dev)
+    OMputSymbol(dev, "combinat1", "binomial")
+    for arg in args repeat
+      OMwrite(dev, arg, false)
+    OMputEndApp(dev)
+
+  outputOMPower(dev: OpenMathDevice, args: List Expression R): Void ==
+    not #args=2 => error "Wrong number of arguments to power"
+    outputOMArith1(dev, "power", args)
+
+  outputOMDefsum(dev: OpenMathDevice, args: List Expression R): Void ==
+    #args ^= 5 => error "Unexpected number of arguments to a defsum"
+    OMputApp(dev)
+    OMputSymbol(dev, "arith1", "sum")
+    outputOMIntInterval(dev, args.4, args.5)
+    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+    OMputEndApp(dev)
+
+  outputOMDefprod(dev: OpenMathDevice, args: List Expression R): Void ==
+    #args ^= 5 => error "Unexpected number of arguments to a defprod"
+    OMputApp(dev)
+    OMputSymbol(dev, "arith1", "product")
+    outputOMIntInterval(dev, args.4, args.5)
+    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+    OMputEndApp(dev)
+
+  outputOMDefint(dev: OpenMathDevice, args: List Expression R): Void ==
+    #args ^= 5 => error "Unexpected number of arguments to a defint"
+    OMputApp(dev)
+    OMputSymbol(dev, "calculus1", "defint")
+    outputOMInterval(dev, args.4, args.5)
+    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+    OMputEndApp(dev)
+
+  outputOMInt(dev: OpenMathDevice, args: List Expression R): Void ==
+    #args ^= 3 => error "Unexpected number of arguments to a defint"
+    OMputApp(dev)
+    OMputSymbol(dev, "calculus1", "int")
+    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+    OMputEndApp(dev)
+
+  outputOMFunction(dev: OpenMathDevice, op: Symbol, args: List Expression R): Void ==
+    nargs := #args
+    zero? nargs =>
+      omOp: Union(SymInfo, "failed") := search(op, nullaryFunctionAList)
+      omOp case "failed" =>
+        error concat ["No OpenMath definition for nullary function ", coerce op]
+      OMputSymbol(dev, omOp.cd, omOp.name)
+--    one? nargs =>
+    (nargs = 1) =>
+      omOp: Union(SymInfo, "failed") := search(op, unaryFunctionAList)
+      omOp case "failed" =>
+        error concat ["No OpenMath definition for unary function ", coerce op]
+      OMputApp(dev)
+      OMputSymbol(dev, omOp.cd, omOp.name)
+      for arg in args repeat
+        OMwrite(dev, arg, false)
+      OMputEndApp(dev)
+    -- Most of the binary operators cannot be handled trivialy like the
+    -- unary ones since they have bound variables of one kind or another.
+    -- The special functions should be straightforward, but we don't have
+    -- a CD for them yet :-)
+    op = %defint  => outputOMDefint(dev, args)
+    op = integral => outputOMInt(dev, args)
+    op = %defsum  => outputOMDefsum(dev, args)
+    op = %defprod => outputOMDefprod(dev, args)
+    op = %power   => outputOMPower(dev, args)
+    op = binomial => outputOMBinomial(dev, args)
+    error concat ["No OpenMath definition for function ", string op]
+ 
+  outputOMExpr(dev: OpenMathDevice, ex: Expression R): Void ==
+    ground? ex => OMwrite(dev, ground ex, false)
+    not((v := retractIfCan(ex)@Union(Symbol,"failed")) case "failed") =>
+      OMputVariable(dev, v)
+    not((w := isPlus ex) case "failed") => outputOMArith1(dev, "plus", w)
+    not((w := isTimes ex) case "failed") => outputOMArith1(dev, "times", w)
+    --not((y := isMult ex) case "failed") =>
+    --  outputOMArith("times", [OMwrite(y.coef)$Integer,
+    --          OMwrite(coerce y.var)])
+    -- At the time of writing we don't need both isExpt and isPower
+    -- here but they may be relevent when we integrate this stuff into
+    -- the main Expression code.  Note that if we don't check that
+    -- the exponent is non-trivial we get thrown into an infinite recursion.
+--    not (((x := isExpt ex) case "failed") or one? x.exponent) =>
+    not (((x := isExpt ex) case "failed") or (x.exponent = 1)) =>
+      not((s := symbolIfCan(x.var)@Union(Symbol,"failed")) case "failed") =>
+        --outputOMPower(dev, [s::Expression(R), (x.exponent)::Expression(R)])
+        OMputApp(dev)
+        OMputSymbol(dev, "arith1", "power")
+        OMputVariable(dev, s)
+        OMputInteger(dev, x.exponent)
+        OMputEndApp(dev)
+      -- TODO: add error handling code here...
+--    not (((z := isPower ex) case "failed") or one? z.exponent) =>
+    not (((z := isPower ex) case "failed") or (z.exponent = 1)) =>
+      outputOMPower(dev, [ z.val, z.exponent::Expression R ])
+      --OMputApp(dev)
+      --OMputSymbol(dev, "arith1", "power")
+      --outputOMExpr(dev, z.val)
+      --OMputInteger(dev, z.exponent)
+      --OMputEndApp(dev)
+    -- Must only be one top-level Kernel by this point
+    k : Kernel Expression R := first kernels ex
+    outputOMFunction(dev, name operator k, argument k)
+
+
+  ----------
+  -- Exports
+  ----------
+
+  OMwrite(ex: Expression R): String ==
+    s: String := ""
+    sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+    dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
+    OMputObject(dev)
+    outputOMExpr(dev, ex)
+    OMputEndObject(dev)
+    OMclose(dev)
+    s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+    s
+
+  OMwrite(ex: Expression R, wholeObj: Boolean): String ==
+    s: String := ""
+    sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+    dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
+    if wholeObj then
+      OMputObject(dev)
+    outputOMExpr(dev, ex)
+    if wholeObj then
+      OMputEndObject(dev)
+    OMclose(dev)
+    s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+    s
+
+  OMwrite(dev: OpenMathDevice, ex: Expression R): Void ==
+    OMputObject(dev)
+    outputOMExpr(dev, ex)
+    OMputEndObject(dev)
+
+  OMwrite(dev: OpenMathDevice, ex: Expression R, wholeObj: Boolean): Void ==
+    if wholeObj then
+      OMputObject(dev)
+    outputOMExpr(dev, ex)
+    if wholeObj then
+      OMputEndObject(dev)
+
+@
+<<OMEXPR.dotabb>>=
+"OMEXPR" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OMEXPR"]
+"FS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FS"]
+"OMEXPR" -> "FS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package EXPR2UPS ExpressionToUnivariatePowerSeries}
 \pagehead{ExpressionToUnivariatePowerSeries}{EXPR2UPS}
 \pagepic{ps/v104expressiontounivariatepowerseries.ps}{EXPR2UPS}{1.00}
@@ -52822,6 +54415,213 @@ NumberFieldIntegralBasis(UP,F): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package NUMFMT NumberFormats}
+\pagehead{NumberFormats}{NUMFMT}
+\pagepic{ps/v104numberformats.ps}{NUMFMT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package NUMFMT NumberFormats>>=
+)abbrev package NUMFMT NumberFormats
+++ SMW March 88
+++ Keywords: string manipulation, roman numerals, format
+++ Description:
+++ NumberFormats provides function to format and read arabic and
+++ roman numbers, to convert numbers to strings and to read
+++ floating-point numbers.
+
+NumberFormats(): NFexports == NFimplementation where
+    PI ==> PositiveInteger
+    I  ==> Integer
+    C  ==> Character
+    F  ==> Float
+    S  ==> String
+    V  ==> PrimitiveArray
+
+    NFexports ==> with
+        FormatArabic: PI -> S
+            ++ FormatArabic(n) forms an Arabic numeral
+            ++ string from an integer n.
+        ScanArabic:   S -> PI
+            ++ ScanArabic(s) forms an integer from an Arabic numeral string s.
+        FormatRoman:  PI -> S
+            ++ FormatRoman(n) forms a Roman numeral string from an integer n.
+        ScanRoman:    S -> PI
+            ++ ScanRoman(s) forms an integer from a Roman numeral string s.
+        ScanFloatIgnoreSpaces: S -> F
+            ++ ScanFloatIgnoreSpaces(s) forms a floating point number from
+            ++ the string s ignoring any spaces. Error is generated if the
+            ++ string is not recognised as a floating point number.
+        ScanFloatIgnoreSpacesIfCan: S -> Union(F, "failed")
+            ++ ScanFloatIgnoreSpacesIfCan(s) tries to form a floating point
+            ++ number from the string s ignoring any spaces.
+
+
+    NFimplementation ==> add
+        import SExpression
+        import Symbol
+        replaceD: C -> C
+        replaced: C -> C
+        contract: S -> S
+        check: S ->Boolean
+        replaceD c ==
+          if c = char "D" then char "E" else c
+        replaced c ==
+          if c = char "d" then char "E" else c
+        contract s ==
+          s:= map(replaceD,s)
+          s:= map(replaced,s)
+          ls:List S := split(s,char " ")$String
+          s:= concat ls
+        check s ==
+          NUMBERP(READ_-FROM_-STRING(s)$Lisp)$Lisp and
+           -- if there is an "E" then there must be a "."
+           -- this is not caught by code above
+           -- also if the exponent is v.big the above returns false
+           not (any?(#1=char "E",s) and not any?(#1=char ".",s) )
+
+--        Original interpreter function:
+--        )lis (defun scanstr(x) (spadcomp::|parseFromString| x))
+        sexfloat:SExpression:=convert(coerce("Float")@Symbol)$SExpression
+        ScanFloatIgnoreSpaces s ==
+          s := contract s
+          not check s => error "Non-numeric value"
+          sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
+          sCheck := car(car(sex))
+          if (sCheck=sexfloat) = true then
+             f := (cdr cdr sex) pretend Float
+          else
+             if integer?(cdr sex) = true then
+                f := (cdr sex) pretend Integer
+                f::F
+             else
+                error "Non-numeric value"
+
+        ScanFloatIgnoreSpacesIfCan s ==
+          s := contract s
+	  not check s => "failed"
+          sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
+          sCheck := car(car(sex))
+          if (sCheck=sexfloat) = true then
+             f := (cdr cdr sex) pretend Float
+          else
+             if integer?(cdr sex) = true then
+                f := (cdr sex) pretend Integer
+                f::F
+             else
+                "failed"
+
+        units:V S :=
+           construct ["","I","II","III","IV","V","VI","VII","VIII","IX"]
+        tens :V S :=
+           construct ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"]
+        hunds:V S :=
+           construct ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]
+        umin := minIndex units
+        tmin := minIndex tens
+        hmin := minIndex hunds
+        romval:V I := new(256, -1)
+        romval ord char(" ")$C := 0
+        romval ord char("I")$C := 1
+        romval ord char("V")$C := 5
+        romval ord char("X")$C := 10
+        romval ord char("L")$C := 50
+        romval ord char("C")$C := 100
+        romval ord char("D")$C := 500
+        romval ord char("M")$C := 1000
+        thou:C  := char "M"
+        plen:C  := char "("
+        pren:C  := char ")"
+        ichar:C := char "I"
+
+        FormatArabic n == STRINGIMAGE(n)$Lisp
+        ScanArabic   s == PARSE_-INTEGER(s)$Lisp
+
+        FormatRoman pn ==
+            n := pn::Integer
+            -- Units
+            d := (n rem 10) + umin
+            n := n quo 10
+            s := units.d
+            zero? n => s
+            -- Tens
+            d := (n rem 10) + tmin
+            n := n quo 10
+            s := concat(tens.d, s)
+            zero? n => s
+            -- Hundreds
+            d := (n rem 10) + hmin
+            n := n quo 10
+            s := concat(hunds.d, s)
+            zero? n => s
+            -- Thousands
+            d := n rem 10
+            n := n quo 10
+            s := concat(new(d::NonNegativeInteger, thou), s)
+            zero? n => s
+            -- Ten thousand and higher
+            for i in 2.. while not zero? n repeat
+                -- Coefficient of 10**(i+2)
+                d := n rem 10
+                n := n quo 10
+                zero? d => "iterate"
+                m0:String := concat(new(i,plen),concat("I",new(i,pren)))
+                mm := concat([m0 for j in 1..d]$List(String))
+                -- strictly speaking the blank is gratuitous
+                if #s > 0 then s := concat(" ", s)
+                s  := concat(mm, s)
+            s
+
+        -- ScanRoman
+        --
+        -- The Algorithm:
+        --    Read number from right to left.  When the current
+        --    numeral is lower in magnitude than the previous maximum
+        --    then subtract otherwise add.
+        --    Shift left and repeat until done.
+
+        ScanRoman s ==
+            s      := upperCase s
+            tot: I := 0
+            Max: I := 0
+            i:   I := maxIndex s
+            while i >= minIndex s repeat
+                -- Read a single roman digit
+                c := s.i; i := i-1
+                n := romval ord c
+                -- (I)=1000, ((I))=10000, (((I)))=100000, etc
+                if n < 0 then
+                    c ^= pren =>
+                       error ["Improper character in Roman numeral: ",c]
+                    nprens: PI := 1
+                    while c = pren and i >= minIndex s repeat
+                       c := s.i; i := i-1
+                       if c = pren then nprens := nprens+1
+                    c ^= ichar =>
+                       error "Improper Roman numeral: (x)"
+                    for k in 1..nprens while i >= minIndex s repeat
+                       c := s.i; i := i-1
+                       c ^= plen =>
+                          error "Improper Roman numeral: unbalanced ')'"
+                    n := 10**(nprens + 2)
+                if n < Max then
+                    tot := tot - n
+                else
+                    tot := tot + n
+                    Max := n
+            tot < 0 => error ["Improper Roman numeral: ", tot]
+            tot::PI
+
+@
+<<NUMFMT.dotabb>>=
+"NUMFMT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=NUMFMT"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"NUMFMT" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package NUMERIC Numeric}
 \pagehead{Numeric}{NUMERIC}
 \pagepic{ps/v104numeric.ps}{NUMERIC}{1.00}
@@ -54462,6 +56262,243 @@ NumericRealEigenPackage(Par) : C == T
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter O}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OCTCT2 OctonionCategoryFunctions2}
+\pagehead{OctonionCategoryFunctions2}{OCTCT2}
+\pagepic{ps/v104octonioncategoryfunctions2.ps}{OCTCT2}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OCTCT2 OctonionCategoryFunctions2>>=
+)abbrev package OCTCT2 OctonionCategoryFunctions2
+--% OctonionCategoryFunctions2
+++ Author: Johannes Grabmeier
+++ Date Created: 10 September 1990
+++ Date Last Updated: 10 September 1990
+++ Basic Operations: map
+++ Related Constructors: 
+++ Also See: 
+++ AMS Classifications:
+++ Keywords: octonion, non-associative algebra, Cayley-Dixon  
+++ References:
+++ Description:
+++  OctonionCategoryFunctions2 implements functions between
+++  two octonion domains defined over different rings. 
+++  The function map is used 
+++  to coerce between octonion types.
+ 
+OctonionCategoryFunctions2(OR,R,OS,S) : Exports ==
+  Implementation where
+    R  : CommutativeRing
+    S  : CommutativeRing
+    OR : OctonionCategory R
+    OS : OctonionCategory S
+    Exports == with
+      map:     (R -> S, OR) -> OS
+        ++ map(f,u) maps f onto the component parts of the octonion
+        ++ u.
+    Implementation == add
+      map(fn : R -> S, u : OR): OS ==
+        octon(fn real u, fn imagi u, fn imagj u, fn imagk u,_
+        fn imagE u, fn imagI u, fn imagJ u, fn imagK u)$OS
+
+@
+<<OCTCT2.dotabb>>=
+"OCTCT2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OCTCT2"]
+"OC" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OC"]
+"OCTCT2" -> "OC"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODEINT ODEIntegration}
+\pagehead{ODEIntegration}{ODEINT}
+\pagepic{ps/v104odeintegration.ps}{ODEINT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODEINT ODEIntegration>>=
+)abbrev package ODEINT ODEIntegration
+++ Author: Manuel Bronstein
+++ Date Created: 4 November 1991
+++ Date Last Updated: 2 February 1994
+++ Description:
+++ \spadtype{ODEIntegration} provides an interface to the integrator.
+++ This package is intended for use
+++ by the differential equations solver but not at top-level.
+ODEIntegration(R, F): Exports == Implementation where
+  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+          LinearlyExplicitRingOver Integer, CharacteristicZero)
+  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+                                              PrimitiveFunctionCategory)
+
+  Q   ==> Fraction Integer
+  UQ  ==> Union(Q, "failed")
+  SY  ==> Symbol
+  K   ==> Kernel F
+  P   ==> SparseMultivariatePolynomial(R, K)
+  REC ==> Record(coef:Q, logand:F)
+
+  Exports ==> with
+    int   : (F, SY) -> F
+      ++ int(f, x) returns the integral of f with respect to x.
+    expint: (F, SY) -> F
+      ++ expint(f, x) returns e^{the integral of f with respect to x}.
+    diff  : SY -> (F -> F)
+      ++ diff(x) returns the derivation with respect to x.
+
+  Implementation ==> add
+    import FunctionSpaceIntegration(R, F)
+    import ElementaryFunctionStructurePackage(R, F)
+
+    isQ   : List F -> UQ
+    isQlog: F -> Union(REC, "failed")
+    mkprod: List REC -> F
+
+    diff x == differentiate(#1, x)
+
+-- This is the integration function to be used for quadratures
+    int(f, x) ==
+      (u := integrate(f, x)) case F => u::F
+      first(u::List(F))
+
+-- mkprod([q1, f1],...,[qn,fn]) returns */(fi^qi) but groups the
+-- qi having the same denominator together
+    mkprod l ==
+      empty? l => 1
+      rec := first l
+      d := denom(rec.coef)
+      ll := select(denom(#1.coef) = d, l)
+      nthRoot(*/[r.logand ** numer(r.coef) for r in ll], d) *
+        mkprod setDifference(l, ll)
+
+-- computes exp(int(f,x)) in a non-naive way
+    expint(f, x) ==
+      a := int(f, x)
+      (u := validExponential(tower a, a, x)) case F => u::F
+      da := denom a
+      l :=
+        (v := isPlus(na := numer a)) case List(P) => v::List(P)
+        [na]
+      exponent:P := 0
+      lrec:List(REC) := empty()
+      for term in l repeat
+        if (w := isQlog(term / da)) case REC then
+          lrec := concat(w::REC, lrec)
+        else
+          exponent := exponent + term
+      mkprod(lrec) * exp(exponent / da)
+
+-- checks if all the elements of l are rational numbers, returns their product
+    isQ l ==
+      prod:Q := 1
+      for x in l repeat
+        (u := retractIfCan(x)@UQ) case "failed" => return "failed"
+        prod := prod * u::Q
+      prod
+
+-- checks if a non-sum expr is of the form c * log(g) for a rational number c
+    isQlog f ==
+      is?(f, "log"::SY) => [1, first argument(retract(f)@K)]
+      (v := isTimes f) case List(F) and (#(l := v::List(F)) <= 3) =>
+          l := reverse_! sort_! l
+          is?(first l, "log"::SY) and ((u := isQ rest l) case Q) =>
+              [u::Q, first argument(retract(first(l))@K)]
+          "failed"
+      "failed"
+
+@
+<<ODEINT.dotabb>>=
+"ODEINT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODEINT"]
+"ACFS" [color="#4488FF",href="bookvol10.2.pdf#nameddest=ACFS"]
+"ODEINT" -> "ACFS"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODETOOLS ODETools}
+\pagehead{ODETools}{ODETOOLS}
+\pagepic{ps/v104odetools.ps}{ODETOOLS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODETOOLS ODETools>>=
+)abbrev package ODETOOLS ODETools
+++ Author: Manuel Bronstein
+++ Date Created: 20 March 1991
+++ Date Last Updated: 2 February 1994
+++ Description:
+++   \spad{ODETools} provides tools for the linear ODE solver.
+ODETools(F, LODO): Exports == Implementation where
+  N ==> NonNegativeInteger
+  L ==> List F
+  V ==> Vector F
+  M ==> Matrix F
+
+  F:    Field
+  LODO: LinearOrdinaryDifferentialOperatorCategory F
+
+  Exports ==> with
+    wronskianMatrix: L -> M
+      ++ wronskianMatrix([f1,...,fn]) returns the \spad{n x n} matrix m
+      ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
+    wronskianMatrix: (L, N) -> M
+      ++ wronskianMatrix([f1,...,fn], q, D) returns the \spad{q x n} matrix m
+      ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
+    variationOfParameters: (LODO, F, L) -> Union(V, "failed")
+      ++ variationOfParameters(op, g, [f1,...,fm])
+      ++ returns \spad{[u1,...,um]} such that a particular solution of the
+      ++ equation \spad{op y = g} is \spad{f1 int(u1) + ... + fm int(um)}
+      ++ where \spad{[f1,...,fm]} are linearly independent and \spad{op(fi)=0}.
+      ++ The value "failed" is returned if \spad{m < n} and no particular
+      ++ solution is found.
+    particularSolution: (LODO, F, L, F -> F) -> Union(F, "failed")
+      ++ particularSolution(op, g, [f1,...,fm], I) returns a particular
+      ++ solution h of the equation \spad{op y = g} where \spad{[f1,...,fm]}
+      ++ are linearly independent and \spad{op(fi)=0}.
+      ++ The value "failed" is returned if no particular solution is found.
+      ++ Note: the method of variations of parameters is used.
+
+  Implementation ==> add
+    import LinearSystemMatrixPackage(F, V, V, M)
+
+    diff := D()$LODO
+
+    wronskianMatrix l == wronskianMatrix(l, #l)
+
+    wronskianMatrix(l, q) ==
+      v:V := vector l
+      m:M := zero(q, #v)
+      for i in minRowIndex m .. maxRowIndex m repeat
+        setRow_!(m, i, v)
+        v := map_!(diff #1, v)
+      m
+
+    variationOfParameters(op, g, b) ==
+      empty? b => "failed"
+      v:V := new(n := degree op, 0)
+      qsetelt_!(v, maxIndex v, g / leadingCoefficient op)
+      particularSolution(wronskianMatrix(b, n), v)
+
+    particularSolution(op, g, b, integration) ==
+      zero? g => 0
+      (sol := variationOfParameters(op, g, b)) case "failed" => "failed"
+      ans:F := 0
+      for f in b for i in minIndex(s := sol::V) .. repeat
+        ans := ans + integration(qelt(s, i)) * f
+      ans
+
+@
+<<ODETOOLS.dotabb>>=
+"ODETOOLS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODETOOLS"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"ODETOOLS" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ARRAY12 OneDimensionalArrayFunctions2}
 \pagehead{OneDimensionalArrayFunctions2}{ARRAY12}
 \pagepic{ps/v104onedimensionalarrayfunctions2.ps}{ARRAY12}{1.00}
@@ -54571,6 +56608,178 @@ OnePointCompletionFunctions2(R, S): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OMPKG OpenMathPackage}
+\pagehead{OpenMathPackage}{OMPKG}
+\pagepic{ps/v104openmathpackage.ps}{OMPKG}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OMPKG OpenMathPackage>>=
+)abbrev package OMPKG OpenMathPackage
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathPackage} provides some simple utilities 
+++ to make reading OpenMath objects easier.
+
+OpenMathPackage(): with
+  OMread            : OpenMathDevice -> Any
+  ++ OMread(dev) reads an OpenMath object from \axiom{dev} and passes it
+  ++ to AXIOM.
+  OMreadFile        : String -> Any
+  ++ OMreadFile(f) reads an OpenMath object from \axiom{f} and passes it
+  ++ to AXIOM.
+  OMreadStr         : String -> Any
+  ++ OMreadStr(f) reads an OpenMath object from \axiom{f} and passes it
+  ++ to AXIOM.
+  OMlistCDs         : () -> List(String)
+  ++ OMlistCDs() lists all the CDs supported by AXIOM.
+  OMlistSymbols     : String -> List(String)
+  ++ OMlistSymbols(cd) lists all the symbols in \axiom{cd}.
+  OMsupportsCD?      : String -> Boolean
+  ++ OMsupportsCD?(cd) returns true if AXIOM supports \axiom{cd}, false 
+  ++ otherwise.
+  OMsupportsSymbol? : (String, String) -> Boolean
+  ++ OMsupportsSymbol?(s,cd) returns true if AXIOM supports symbol \axiom{s}
+  ++ from CD \axiom{cd}, false otherwise.
+  OMunhandledSymbol : (String, String) -> Exit
+  ++ OMunhandledSymbol(s,cd) raises an error if AXIOM reads a symbol which it
+  ++ is unable to handle.  Note that this is different from an unexpected
+  ++ symbol.
+ == add
+  import OpenMathEncoding
+  import OpenMathDevice
+  import String
+
+  OMunhandledSymbol(u,v) ==
+    error concat ["AXIOM is unable to process the symbol ",u," from CD ",v,"."]
+
+  OMread(dev: OpenMathDevice): Any ==
+    interpret(OM_-READ(dev)$Lisp :: InputForm)
+
+  OMreadFile(filename: String): Any ==
+    dev := OMopenFile(filename, "r", OMencodingUnknown())
+    res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
+    OMclose(dev)
+    res
+
+  OMreadStr(str: String): Any ==
+    strp := OM_-STRINGTOSTRINGPTR(str)$Lisp
+    dev := OMopenString(strp pretend String, OMencodingUnknown())
+    res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
+    OMclose(dev)
+    res
+
+  OMlistCDs(): List(String) ==
+    OM_-LISTCDS()$Lisp pretend List(String)
+
+  OMlistSymbols(cd: String): List(String) ==
+    OM_-LISTSYMBOLS(cd)$Lisp pretend List(String)
+
+  import SExpression
+
+  OMsupportsCD?(cd: String): Boolean ==
+    not null? OM_-SUPPORTSCD(cd)$Lisp 
+
+  OMsupportsSymbol?(cd: String, name: String): Boolean ==
+    not null? OM_-SUPPORTSSYMBOL(cd, name)$Lisp
+
+@
+<<OMPKG.dotabb>>=
+"OMPKG" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OMPKG"]
+"STRING" [color="#88FF44",href="bookvol10.3.pdf#nameddest=STRING"]
+"OMPKG" -> "STRING"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OMSERVER OpenMathServerPackage}
+\pagehead{OpenMathServerPackage}{OMSERVER}
+\pagepic{ps/v104openmathserverpackage.ps}{OMSERVER}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OMSERVER OpenMathServerPackage>>=
+)abbrev package OMSERVER OpenMathServerPackage
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathServerPackage} provides the necessary
+++ operations to run AXIOM as an OpenMath server, reading/writing objects
+++ to/from a port.  Please note the facilities available here are very basic.
+++ The idea is that a user calls e.g. \axiom{Omserve(4000,60)} and then
+++ another process sends OpenMath objects to port 4000 and reads the result.
+
+OpenMathServerPackage(): with
+  OMreceive : OpenMathConnection -> Any
+  ++ OMreceive(c) reads an OpenMath object from connection \axiom{c} and
+  ++ returns the appropriate AXIOM object.
+  OMsend    : (OpenMathConnection, Any) -> Void
+  ++ OMsend(c,u) attempts to output \axiom{u} on \axiom{c} in OpenMath.
+  OMserve   : (SingleInteger, SingleInteger) -> Void
+  ++ OMserve(portnum,timeout) puts AXIOM into server mode on port number
+  ++ \axiom{portnum}.  The parameter \axiom{timeout} specifies the timeout
+  ++ period for the connection.
+ == add
+  import OpenMathDevice
+  import OpenMathConnection
+  import OpenMathPackage
+  import OpenMath
+
+
+
+  OMreceive(conn: OpenMathConnection): Any ==
+    dev: OpenMathDevice := OMconnInDevice(conn)
+    OMsetEncoding(dev, OMencodingUnknown);
+    OMread(dev)
+
+  OMsend(conn: OpenMathConnection, value: Any): Void ==
+    dev: OpenMathDevice := OMconnOutDevice(conn)
+    OMsetEncoding(dev, OMencodingXML);
+    --retractable?(value)$AnyFunctions1(Expression Integer) =>
+    --  OMwrite(dev, retract(value)$AnyFunctions1(Expression Integer), true)
+    retractable?(value)$AnyFunctions1(Integer) =>
+      OMwrite(dev, retract(value)$AnyFunctions1(Integer), true)
+    retractable?(value)$AnyFunctions1(Float) =>
+      OMwrite(dev, retract(value)$AnyFunctions1(Float), true)
+    retractable?(value)$AnyFunctions1(SingleInteger) =>
+      OMwrite(dev, retract(value)$AnyFunctions1(SingleInteger), true)
+    retractable?(value)$AnyFunctions1(DoubleFloat) =>
+      OMwrite(dev, retract(value)$AnyFunctions1(DoubleFloat), true)
+    retractable?(value)$AnyFunctions1(String) =>
+      OMwrite(dev, retract(value)$AnyFunctions1(String), true)
+
+  OMserve(portNum: SingleInteger, timeout: SingleInteger): Void ==
+    conn: OpenMathConnection := OMmakeConn(timeout)
+    OMbindTCP(conn, portNum)
+    val: Any
+    while true repeat
+      val := OMreceive(conn)
+      OMsend(conn, val)
+
+@
+<<OMSERVER.dotabb>>=
+"OMSERVER" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OMSERVER"]
+"STRING" [color="#88FF44",href="bookvol10.3.pdf#nameddest=STRING"]
+"OMSERVER" -> "STRING"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package ORDCOMP2 OrderedCompletionFunctions2}
 \pagehead{OrderedCompletionFunctions2}{ORDCOMP2}
 \pagepic{ps/v104orderedcompletionfunctions2.ps}{ORDCOMP2}{1.00}
@@ -54735,6 +56944,77 @@ OperationsQuery(): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OUT OutputPackage}
+\pagehead{OutputPackage}{OUT}
+\pagepic{ps/v104outputpackage.ps}{OUT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OUT OutputPackage>>=
+)abbrev package OUT OutputPackage
+++ Author: Stephen M. Watt
+++ Date Created: February 1986
+++ Date Last Updated: October 27 1995 (MCD)
+++ Basic Operations: output
+++ Related Constructors: OutputForm
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: OutPackage allows pretty-printing from programs.
+
+OutputPackage: with
+        output: String -> Void
+            ++ output(s) displays the string s on the ``algebra output''
+            ++ stream, as defined by \spadsyscom{set output algebra}.
+        output: OutputForm -> Void
+            ++ output(x) displays the output form x on the
+            ++ ``algebra output'' stream, as defined by
+            ++ \spadsyscom{set output algebra}.
+        output: (String, OutputForm) -> Void
+            ++ output(s,x) displays the string s followed by the form x
+            ++ on the ``algebra output'' stream, as defined by
+            ++ \spadsyscom{set output algebra}.
+        outputList: (List Any) -> Void
+            ++ outputList(l) displays the concatenated components of the
+            ++ list l on the ``algebra output'' stream, as defined by
+            ++ \spadsyscom{set output algebra}; quotes are stripped
+	    ++ from strings.
+
+    == add
+        --ExpressionPackage()
+        E      ==> OutputForm
+        putout ==> mathprint$Lisp
+
+        s: String
+        e: OutputForm
+        l: List Any
+
+        output e ==
+            mathprint(e)$Lisp
+            void()
+        output s ==
+            output(s:E)
+        output(s,e) ==
+            output blankSeparate [s:E, e]
+        outputList(l) ==                                -- MGR
+	  output hconcat
+	    [if retractable?(x)$AnyFunctions1(String) then
+                message(retract(x)$AnyFunctions1(String))$OutputForm
+              else
+                x::OutputForm
+             for x in l]
+
+@
+<<OUT.dotabb>>=
+"OUT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OUT"]
+"Package" [color="#FF4488"]
+"OUT" -> "Package"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter P}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PMASS PatternMatchAssertions}
@@ -56454,6 +58734,200 @@ PrimitiveArrayFunctions2(A, B): Exports == Implementation where
 @
 <<PRIMARR2.dotabb>>=
 "PRIMARR2" [color="#FF4488",href="bookvol10.4.pdf#nameddest=PRIMARR2"]
+"A1AGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=A1AGG"]
+"PRIMARR2" -> "A1AGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODEPRIM PrimitiveRatDE}
+\pagehead{PrimitiveRatDE}{ODEPRIM}
+\pagepic{ps/v104primitiveratde.ps}{ODEPRIM}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODEPRIM PrimitiveRatDE>>=
+)abbrev package ODEPRIM PrimitiveRatDE
+++ Author: Manuel Bronstein
+++ Date Created: 1 March 1991
+++ Date Last Updated: 1 February 1994
+++ Description:
+++  \spad{PrimitiveRatDE} provides functions for in-field solutions of linear
+++   ordinary differential equations, in the transcendental case.
+++   The derivation to use is given by the parameter \spad{L}.
+PrimitiveRatDE(F, UP, L, LQ): Exports == Implementation where
+  F  : Join(Field, CharacteristicZero, RetractableTo Fraction Integer)
+  UP : UnivariatePolynomialCategory F
+  L  : LinearOrdinaryDifferentialOperatorCategory UP
+  LQ : LinearOrdinaryDifferentialOperatorCategory Fraction UP
+
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  RF  ==> Fraction UP
+  UP2 ==> SparseUnivariatePolynomial UP
+  REC ==> Record(center:UP, equation:UP)
+
+  Exports ==> with
+    denomLODE: (L, RF) -> Union(UP, "failed")
+      ++ denomLODE(op, g) returns a polynomial d such that
+      ++ any rational solution of \spad{op y = g}
+      ++ is of the form \spad{p/d} for some polynomial p, and
+      ++ "failed", if the equation has no rational solution.
+    denomLODE: (L, List RF) -> UP
+      ++ denomLODE(op, [g1,...,gm]) returns a polynomial
+      ++ d such that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+      ++ is of the form \spad{p/d} for some polynomial p.
+    indicialEquations: L -> List REC
+      ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
+      ++ the \spad{d_i}'s are the affine singularities of \spad{op},
+      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+    indicialEquations: (L, UP) -> List REC
+      ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
+      ++ the \spad{d_i}'s are the affine singularities of \spad{op}
+      ++ above the roots of \spad{p},
+      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+    indicialEquation: (L, F) -> UP
+      ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
+      ++ at \spad{a}.
+    indicialEquations: LQ -> List REC
+      ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
+      ++ the \spad{d_i}'s are the affine singularities of \spad{op},
+      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+    indicialEquations: (LQ, UP) -> List REC
+      ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
+      ++ the \spad{d_i}'s are the affine singularities of \spad{op}
+      ++ above the roots of \spad{p},
+      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+    indicialEquation: (LQ, F) -> UP
+      ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
+      ++ at \spad{a}.
+    splitDenominator: (LQ, List RF) -> Record(eq:L, rh:List RF)
+      ++ splitDenominator(op, [g1,...,gm]) returns \spad{op0, [h1,...,hm]}
+      ++ such that the equations \spad{op y = c1 g1 + ... + cm gm} and
+      ++ \spad{op0 y = c1 h1 + ... + cm hm} have the same solutions.
+
+  Implementation ==> add
+    import BoundIntegerRoots(F, UP)
+    import BalancedFactorisation(F, UP)
+    import InnerCommonDenominator(UP, RF, List UP, List RF)
+    import UnivariatePolynomialCategoryFunctions2(F, UP, UP, UP2)
+
+    tau          : (UP, UP, UP, N) -> UP
+    NPbound      : (UP, L, UP) -> N
+    hdenom       : (L, UP, UP) -> UP
+    denom0       : (Z, L, UP, UP, UP) -> UP
+    indicialEq   : (UP, List N, List UP) -> UP
+    separateZeros: (UP, UP) -> UP
+    UPfact       : N -> UP
+    UP2UP2       : UP -> UP2
+    indeq        : (UP, L) -> UP
+    NPmulambda   : (UP, L) -> Record(mu:Z, lambda:List N, func:List UP)
+
+    diff := D()$L
+
+    UP2UP2 p                    == map(#1::UP, p)
+    indicialEquations(op:L)     == indicialEquations(op, leadingCoefficient op)
+    indicialEquation(op:L, a:F) == indeq(monomial(1, 1) - a::UP, op)
+
+    splitDenominator(op, lg) ==
+      cd := splitDenominator coefficients op
+      f  := cd.den / gcd(cd.num)
+      l:L := 0
+      while op ^= 0 repeat
+          l  := l + monomial(retract(f * leadingCoefficient op), degree op)
+          op := reductum op
+      [l, [f * g for g in lg]]
+
+    tau(p, pp, q, n) ==
+      ((pp ** n) * ((q exquo (p ** order(q, p)))::UP)) rem p
+
+    indicialEquations(op:LQ) ==
+      indicialEquations(splitDenominator(op, empty()).eq)
+
+    indicialEquations(op:LQ, p:UP) ==
+      indicialEquations(splitDenominator(op, empty()).eq, p)
+
+    indicialEquation(op:LQ, a:F) ==
+      indeq(monomial(1, 1) - a::UP, splitDenominator(op, empty()).eq)
+
+-- returns z(z-1)...(z-(n-1))
+    UPfact n ==
+      zero? n => 1
+      z := monomial(1, 1)$UP
+      */[z - i::F::UP for i in 0..(n-1)::N]
+
+    indicialEq(c, lamb, lf) ==
+      cp := diff c
+      cc := UP2UP2 c
+      s:UP2 := 0
+      for i in lamb for f in lf repeat
+        s := s + (UPfact i) * UP2UP2 tau(c, cp, f, i)
+      primitivePart resultant(cc, s)
+
+    NPmulambda(c, l) ==
+      lamb:List(N) := [d := degree l]
+      lf:List(UP) := [a := leadingCoefficient l]
+      mup := d::Z - order(a, c)
+      while (l := reductum l) ^= 0 repeat
+          a := leadingCoefficient l
+          if (m := (d := degree l)::Z - order(a, c)) > mup then
+              mup := m
+              lamb := [d]
+              lf := [a]
+          else if (m = mup) then
+              lamb := concat(d, lamb)
+              lf := concat(a, lf)
+      [mup, lamb, lf]
+
+-- e = 0 means homogeneous equation
+    NPbound(c, l, e) ==
+      rec := NPmulambda(c, l)
+      n := max(0, - integerBound indicialEq(c, rec.lambda, rec.func))
+      zero? e => n::N
+      max(n, order(e, c)::Z - rec.mu)::N
+
+    hdenom(l, d, e) ==
+      */[dd.factor ** NPbound(dd.factor, l, e)
+                    for dd in factors balancedFactorisation(d, coefficients l)]
+
+    denom0(n, l, d, e, h) ==
+      hdenom(l, d, e) * */[hh.factor ** max(0, order(e, hh.factor) - n)::N
+                                 for hh in factors balancedFactorisation(h, e)]
+
+-- returns a polynomials whose zeros are the zeros of e which are not
+-- zeros of d
+    separateZeros(d, e) ==
+      ((g := squareFreePart e) exquo gcd(g, squareFreePart d))::UP
+
+    indeq(c, l) ==
+      rec := NPmulambda(c, l)
+      indicialEq(c, rec.lambda, rec.func)
+
+    indicialEquations(op:L, p:UP) ==
+      [[dd.factor, indeq(dd.factor, op)]
+                   for dd in factors balancedFactorisation(p, coefficients op)]
+
+-- cannot return "failed" in the homogeneous case
+    denomLODE(l:L, g:RF) ==
+      d := leadingCoefficient l
+      zero? g => hdenom(l, d, 0)
+      h := separateZeros(d, e := denom g)
+      n := degree l
+      (e exquo (h**(n + 1))) case "failed" => "failed"
+      denom0(n, l, d, e, h)
+
+    denomLODE(l:L, lg:List RF) ==
+      empty? lg => denomLODE(l, 0)::UP
+      d := leadingCoefficient l
+      h := separateZeros(d, e := "lcm"/[denom g for g in lg])
+      denom0(degree l, l, d, e, h)
+
+@
+<<ODEPRIM.dotabb>>=
+"ODEPRIM" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODEPRIM"]
+"PFECAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=PFECAT"]
+"ODEPRIM" -> "PFECAT"
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -56856,6 +59330,63 @@ PureAlgebraicIntegration(R, F, L): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODEPAL PureAlgebraicLODE}
+\pagehead{PureAlgebraicLODE}{ODEPAL}
+\pagepic{ps/v104purealgebraiclode.ps}{ODEPAL}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODEPAL PureAlgebraicLODE>>=
+)abbrev package ODEPAL PureAlgebraicLODE
+++ Author: Manuel Bronstein
+++ Date Created: 21 August 1991
+++ Date Last Updated: 3 February 1994
+++ Description: In-field solution of an linear ordinary differential equation,
+++ pure algebraic case.
+PureAlgebraicLODE(F, UP, UPUP, R): Exports == Implementation where
+  F   : Join(Field, CharacteristicZero,
+             RetractableTo Integer, RetractableTo Fraction Integer)
+  UP  : UnivariatePolynomialCategory F
+  UPUP: UnivariatePolynomialCategory Fraction UP
+  R   : FunctionFieldCategory(F, UP, UPUP)
+
+  RF  ==> Fraction UP
+  V   ==> Vector RF
+  U   ==> Union(R, "failed")
+  REC ==> Record(particular: Union(RF, "failed"), basis: List RF)
+  L   ==> LinearOrdinaryDifferentialOperator1 R
+  LQ  ==> LinearOrdinaryDifferentialOperator1 RF
+
+  Exports ==> with
+    algDsolve: (L, R) -> Record(particular: U, basis: List R)
+      ++ algDsolve(op, g) returns \spad{["failed", []]} if the equation
+      ++ \spad{op y = g} has no solution in \spad{R}. Otherwise, it returns
+      ++ \spad{[f, [y1,...,ym]]} where \spad{f} is a particular rational
+      ++ solution and the \spad{y_i's} form a basis for the solutions in
+      ++ \spad{R} of the homogeneous equation.
+
+  Implementation ==> add
+    import RationalLODE(F, UP)
+    import SystemODESolver(RF, LQ)
+    import ReduceLODE(RF, LQ, UPUP, R, L)
+
+    algDsolve(l, g) ==
+      rec := reduceLODE(l, g)
+      sol := solveInField(rec.mat, rec.vec, ratDsolve)
+      bas:List(R) := [represents v for v in sol.basis]
+      (u := sol.particular) case V => [represents(u::V), bas]
+      ["failed", bas]
+
+@
+<<ODEPAL.dotabb>>=
+"ODEPAL" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODEPAL"]
+"FFCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=FFCAT"]
+"ODEPAL" -> "FFCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package PUSHVAR PushVariables}
 \pagehead{PushVariables}{PUSHVAR}
 \pagepic{ps/v104pushvariables.ps}{PUSHVAR}{1.00}
@@ -57357,6 +59888,248 @@ RationalIntegration(F, UP): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODERAT RationalLODE}
+\pagehead{RationalLODE}{ODERAT}
+\pagepic{ps/v104rationallode.ps}{ODERAT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODERAT RationalLODE>>=
+)abbrev package ODERAT RationalLODE
+++ Author: Manuel Bronstein
+++ Date Created: 13 March 1991
+++ Date Last Updated: 13 April 1994
+++ Description:
+++  \spad{RationalLODE} provides functions for in-field solutions of linear
+++   ordinary differential equations, in the rational case.
+RationalLODE(F, UP): Exports == Implementation where
+  F  : Join(Field, CharacteristicZero, RetractableTo Integer,
+                                       RetractableTo Fraction Integer)
+  UP : UnivariatePolynomialCategory F
+
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  RF  ==> Fraction UP
+  U   ==> Union(RF, "failed")
+  V   ==> Vector F
+  M   ==> Matrix F
+  LODO ==> LinearOrdinaryDifferentialOperator1 RF
+  LODO2==> LinearOrdinaryDifferentialOperator2(UP, RF)
+
+  Exports ==> with
+    ratDsolve: (LODO, RF) -> Record(particular: U, basis: List RF)
+      ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
+      ++ \spad{op y = g} has no rational solution. Otherwise, it returns
+      ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
+      ++ and the yi's form a basis for the rational solutions of the
+      ++ homogeneous equation.
+    ratDsolve: (LODO, List RF) -> Record(basis:List RF, mat:Matrix F)
+      ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
+      ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+      ++ is of the form \spad{d1 h1 + ... + dq hq} where
+      ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
+    ratDsolve: (LODO2, RF) -> Record(particular: U, basis: List RF)
+      ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
+      ++ \spad{op y = g} has no rational solution. Otherwise, it returns
+      ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
+      ++ and the yi's form a basis for the rational solutions of the
+      ++ homogeneous equation.
+    ratDsolve: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
+      ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
+      ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+      ++ is of the form \spad{d1 h1 + ... + dq hq} where
+      ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
+    indicialEquationAtInfinity: LODO -> UP
+      ++ indicialEquationAtInfinity op returns the indicial equation of
+      ++ \spad{op} at infinity.
+    indicialEquationAtInfinity: LODO2 -> UP
+      ++ indicialEquationAtInfinity op returns the indicial equation of
+      ++ \spad{op} at infinity.
+
+  Implementation ==> add
+    import BoundIntegerRoots(F, UP)
+    import RationalIntegration(F, UP)
+    import PrimitiveRatDE(F, UP, LODO2, LODO)
+    import LinearSystemMatrixPackage(F, V, V, M)
+    import InnerCommonDenominator(UP, RF, List UP, List RF)
+
+    nzero?             : V -> Boolean
+    evenodd            : N -> F
+    UPfact             : N -> UP
+    infOrder           : RF -> Z
+    infTau             : (UP, N) -> F
+    infBound           : (LODO2, List RF) -> N
+    regularPoint       : (LODO2, List RF) -> Z
+    infIndicialEquation: (List N, List UP) -> UP
+    makeDot            : (Vector F, List RF) -> RF
+    unitlist           : (N, N) -> List F
+    infMuLambda: LODO2 -> Record(mu:Z, lambda:List N, func:List UP)
+    ratDsolve0: (LODO2, RF) -> Record(particular: U, basis: List RF)
+    ratDsolve1: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
+    candidates: (LODO2,List RF,UP) -> Record(basis:List RF,particular:List RF)
+
+    dummy := new()$Symbol
+
+    infOrder f == (degree denom f) - (degree numer f)
+    evenodd n  == (even? n => 1; -1)
+
+    ratDsolve1(op, lg) ==
+      d := denomLODE(op, lg)
+      rec := candidates(op, lg, d)
+      l := concat([op q for q in rec.basis],
+                  [op(rec.particular.i) - lg.i for i in 1..#(rec.particular)])
+      sys1 := reducedSystem(matrix [l])@Matrix(UP)
+      [rec.basis, reducedSystem sys1]
+
+    ratDsolve0(op, g) ==
+      zero? degree op => [inv(leadingCoefficient(op)::RF) * g, empty()]
+      minimumDegree op > 0 =>
+        sol := ratDsolve0(monicRightDivide(op, monomial(1, 1)).quotient, g)
+        b:List(RF) := [1]
+        for f in sol.basis repeat
+          if (uu := infieldint f) case RF then b := concat(uu::RF, b)
+        sol.particular case "failed" => ["failed", b]
+        [infieldint(sol.particular::RF), b]
+      (u := denomLODE(op, g)) case "failed" => ["failed", empty()]
+      rec := candidates(op, [g], u::UP)
+      l := lb := lsol := empty()$List(RF)
+      for q in rec.basis repeat
+          if zero?(opq := op q) then lsol := concat(q, lsol)
+          else (l := concat(opq, l); lb := concat(q, lb))
+      h:RF := (zero? g => 0; first(rec.particular))
+      empty? l =>
+          zero? g => [0, lsol]
+          [(g = op h => h; "failed"), lsol]
+      m:M
+      v:V
+      if zero? g then
+          m := reducedSystem(reducedSystem(matrix [l])@Matrix(UP))@M
+          v := new(ncols m, 0)$V
+      else
+          sys1 := reducedSystem(matrix [l], vector [g - op h]
+                               )@Record(mat: Matrix UP, vec: Vector UP)
+          sys2 := reducedSystem(sys1.mat, sys1.vec)@Record(mat:M, vec:V)
+          m := sys2.mat
+          v := sys2.vec
+      sol := solve(m, v)
+      part:U :=
+        zero? g => 0
+        sol.particular case "failed" => "failed"
+        makeDot(sol.particular::V, lb) + first(rec.particular)
+      [part,
+       concat_!(lsol, [makeDot(v, lb) for v in sol.basis | nzero? v])]
+
+    indicialEquationAtInfinity(op:LODO2) ==
+      rec := infMuLambda op
+      infIndicialEquation(rec.lambda, rec.func)
+
+    indicialEquationAtInfinity(op:LODO) ==
+      rec := splitDenominator(op, empty())
+      indicialEquationAtInfinity(rec.eq)
+
+    regularPoint(l, lg) ==
+      a := leadingCoefficient(l) * commonDenominator lg
+      coefficient(a, 0) ^= 0 => 0
+      for i in 1.. repeat
+        a(j := i::F) ^= 0 => return i
+        a(-j) ^= 0 => return(-i)
+
+    unitlist(i, q) ==
+      v := new(q, 0)$Vector(F)
+      v.i := 1
+      parts v
+
+    candidates(op, lg, d) ==
+      n := degree d + infBound(op, lg)
+      m := regularPoint(op, lg)
+      uts := UnivariateTaylorSeries(F, dummy, m::F)
+      tools := UTSodetools(F, UP, LODO2, uts)
+      solver := UnivariateTaylorSeriesODESolver(F, uts)
+      dd := UP2UTS(d)$tools
+      f := LODO2FUN(op)$tools
+      q := degree op
+      e := unitlist(1, q)
+      hom := [UTS2UP(dd * ode(f, unitlist(i, q))$solver, n)$tools /$RF d
+                   for i in 1..q]$List(RF)
+      a1 := inv(leadingCoefficient(op)::RF)
+      part := [UTS2UP(dd * ode(RF2UTS(a1 * g)$tools + f #1, e)$solver, n)$tools
+                /$RF d for g in lg | g ^= 0]$List(RF)
+      [hom, part]
+
+    nzero? v ==
+      for i in minIndex v .. maxIndex v repeat
+        not zero? qelt(v, i) => return true
+      false
+
+-- returns z(z+1)...(z+(n-1))
+    UPfact n ==
+      zero? n => 1
+      z := monomial(1, 1)$UP
+      */[z + i::F::UP for i in 0..(n-1)::N]
+
+    infMuLambda l ==
+      lamb:List(N) := [d := degree l]
+      lf:List(UP) := [a := leadingCoefficient l]
+      mup := degree(a)::Z - d
+      while (l := reductum l) ^= 0 repeat
+          a := leadingCoefficient l
+          if (m := degree(a)::Z - (d := degree l)) > mup then
+            mup := m
+            lamb := [d]
+            lf := [a]
+          else if (m = mup) then
+            lamb := concat(d, lamb)
+            lf := concat(a, lf)
+      [mup, lamb, lf]
+
+    infIndicialEquation(lambda, lf) ==
+      ans:UP := 0
+      for i in lambda for f in lf repeat
+        ans := ans + evenodd i * leadingCoefficient f * UPfact i
+      ans
+
+    infBound(l, lg) ==
+      rec := infMuLambda l
+      n := min(- degree(l)::Z - 1,
+               integerBound infIndicialEquation(rec.lambda, rec.func))
+      while not(empty? lg) and zero? first lg repeat lg := rest lg
+      empty? lg => (-n)::N
+      m := infOrder first lg
+      for g in rest lg repeat
+        if not(zero? g) and (mm := infOrder g) < m then m := mm
+      (-min(n, rec.mu - degree(leadingCoefficient l)::Z + m))::N
+
+    makeDot(v, bas) ==
+      ans:RF := 0
+      for i in 1.. for b in bas repeat ans := ans + v.i::UP * b
+      ans
+
+    ratDsolve(op:LODO, g:RF) ==
+      rec := splitDenominator(op, [g])
+      ratDsolve0(rec.eq, first(rec.rh))
+
+    ratDsolve(op:LODO, lg:List RF) ==
+      rec := splitDenominator(op, lg)
+      ratDsolve1(rec.eq, rec.rh)
+
+    ratDsolve(op:LODO2, g:RF) ==
+      unit?(c := content op) => ratDsolve0(op, g)
+      ratDsolve0((op exquo c)::LODO2, inv(c::RF) * g)
+
+    ratDsolve(op:LODO2, lg:List RF) ==
+      unit?(c := content op) => ratDsolve1(op, lg)
+      ratDsolve1((op exquo c)::LODO2, [inv(c::RF) * g for g in lg])
+
+@
+<<ODERAT.dotabb>>=
+"ODERAT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODERAT"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"ODERAT" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package REALSOLV RealSolvePackage}
 <<RealSolvePackage.input>>=
 -- acplot.spad.pamphlet RealSolvePackage.input
@@ -57647,6 +60420,158 @@ RectangularMatrixCategoryFunctions2(m,n,R1,Row1,Col1,M1,R2,Row2,Col2,M2):_
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODERED ReduceLODE}
+\pagehead{ReduceLODE}{ODERED}
+\pagepic{ps/v104reducelode.ps}{ODERED}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODERED ReduceLODE>>=
+)abbrev package ODERED ReduceLODE
+++ Author: Manuel Bronstein
+++ Date Created: 19 August 1991
+++ Date Last Updated: 11 April 1994
+++ Description: Elimination of an algebraic from the coefficentss
+++ of a linear ordinary differential equation.
+ReduceLODE(F, L, UP, A, LO): Exports == Implementation where
+  F : Field
+  L : LinearOrdinaryDifferentialOperatorCategory F
+  UP: UnivariatePolynomialCategory F
+  A : MonogenicAlgebra(F, UP)
+  LO: LinearOrdinaryDifferentialOperatorCategory A
+
+  V ==> Vector F
+  M ==> Matrix L
+
+  Exports ==> with
+    reduceLODE: (LO, A) -> Record(mat:M, vec:V)
+      ++ reduceLODE(op, g) returns \spad{[m, v]} such that
+      ++ any solution in \spad{A} of \spad{op z = g}
+      ++ is of the form \spad{z = (z_1,...,z_m) . (b_1,...,b_m)} where
+      ++ the \spad{b_i's} are the basis of \spad{A} over \spad{F} returned
+      ++ by \spadfun{basis}() from \spad{A}, and the \spad{z_i's} satisfy the
+      ++ differential system \spad{M.z = v}.
+
+  Implementation ==> add
+    matF2L: Matrix F -> M
+
+    diff := D()$L
+
+-- coerces a matrix of elements of F into a matrix of (order 0) L.O.D.O's
+    matF2L m ==
+      map(#1::L, m)$MatrixCategoryFunctions2(F, V, V, Matrix F,
+                                                L, Vector L, Vector L, M)
+
+-- This follows the algorithm and notation of
+--  "The Risch Differential Equation on an Algebraic Curve", M. Bronstein,
+-- in 'Proceedings of ISSAC '91', Bonn, BRD, ACM Press, pp.241-246, July 1991.
+    reduceLODE(l, g) ==
+      n := rank()$A
+-- md is the basic differential matrix (D x I + Dy)
+      md := matF2L transpose derivationCoordinates(basis(), diff #1)
+      for i in minRowIndex md .. maxRowIndex md
+        for j in minColIndex md .. maxColIndex md repeat
+          md(i, j) := diff + md(i, j)
+-- mdi will go through the successive powers of md
+      mdi := copy md
+      sys := matF2L(transpose regularRepresentation coefficient(l, 0))
+      for i in 1..degree l repeat
+        sys := sys +
+                matF2L(transpose regularRepresentation coefficient(l, i)) * mdi
+        mdi := md * mdi
+      [sys, coordinates g]
+
+@
+<<ODERED.dotabb>>=
+"ODERED" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODERED"]
+"MONOGEN" [color="#4488FF",href="bookvol10.2.pdf#nameddest=MONOGEN"]
+"ODERED" -> "MONOGEN"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package REDORDER ReductionOfOrder}
+\pagehead{ReductionOfOrder}{REDORDER}
+\pagepic{ps/v104reductionoforder.ps}{REDORDER}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package REDORDER ReductionOfOrder>>=
+)abbrev package REDORDER ReductionOfOrder
+++ Author: Manuel Bronstein
+++ Date Created: 4 November 1991
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{ReductionOfOrder} provides
+++ functions for reducing the order of linear ordinary differential equations
+++ once some solutions are known.
+++ Keywords: differential equation, ODE
+ReductionOfOrder(F, L): Exports == Impl where
+  F: Field
+  L: LinearOrdinaryDifferentialOperatorCategory F
+
+  Z ==> Integer
+  A ==> PrimitiveArray F
+
+  Exports ==> with
+    ReduceOrder: (L, F) -> L
+      ++ ReduceOrder(op, s) returns \spad{op1} such that for any solution
+      ++ \spad{z} of \spad{op1 z = 0}, \spad{y = s \int z} is a solution of
+      ++ \spad{op y = 0}. \spad{s} must satisfy \spad{op s = 0}.
+    ReduceOrder: (L, List F) -> Record(eq:L, op:List F)
+      ++ ReduceOrder(op, [f1,...,fk]) returns \spad{[op1,[g1,...,gk]]} such that
+      ++ for any solution \spad{z} of \spad{op1 z = 0},
+      ++ \spad{y = gk \int(g_{k-1} \int(... \int(g1 \int z)...)} is a solution
+      ++ of \spad{op y = 0}. Each \spad{fi} must satisfy \spad{op fi = 0}.
+
+  Impl ==> add
+    ithcoef   : (L, Z, A) -> F
+    locals    : (A, Z, Z) -> F
+    localbinom: (Z, Z) -> Z
+
+    diff := D()$L
+
+    localbinom(j, i) == (j > i => binomial(j, i+1); 0)
+    locals(s, j, i)  == (j > i => qelt(s, j - i - 1); 0)
+
+    ReduceOrder(l:L, sols:List F) ==
+      empty? sols => [l, empty()]
+      neweq := ReduceOrder(l, sol := first sols)
+      rec := ReduceOrder(neweq, [diff(s / sol) for s in rest sols])
+      [rec.eq, concat_!(rec.op, sol)]
+
+    ithcoef(eq, i, s) ==
+      ans:F := 0
+      while eq ^= 0 repeat
+          j   := degree eq
+          ans := ans + localbinom(j, i) * locals(s,j,i) * leadingCoefficient eq
+          eq  := reductum eq
+      ans
+
+    ReduceOrder(eq:L, sol:F) ==
+      s:A := new(n := degree eq, 0)         -- will contain derivatives of sol
+      si := sol                             -- will run through the derivatives
+      qsetelt_!(s, 0, si)
+      for i in 1..(n-1)::NonNegativeInteger repeat 
+          qsetelt_!(s, i, si := diff si)
+      ans:L := 0
+      for i in 0..(n-1)::NonNegativeInteger repeat
+          ans := ans + monomial(ithcoef(eq, i, s), i)
+      ans
+
+@
+<<REDORDER.dotabb>>=
+"REDORDER" [color="#FF4488",href="bookvol10.4.pdf#nameddest=REDORDER"]
+"OREPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OREPCAT"]
+"A1AGG" [color="#4488FF",href="bookvol10.2.pdf#nameddest=A1AGG"]
+"REDORDER" -> "OREPCAT"
+"REDORDER" -> "A1AGG"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package REPDB RepeatedDoubling}
 \pagehead{RepeatedDoubling}{REPDB}
 \pagepic{ps/v104repeateddoubling.ps}{REPDB}{1.00}
@@ -58076,6 +61001,100 @@ SortedCache(S:CachableSet): Exports == Implementation where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package SPECOUT SpecialOutputPackage}
+\pagehead{SpecialOutputPackage}{SPECOUT}
+\pagepic{ps/v104specialoutputpackage.ps}{SPECOUT}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package SPECOUT SpecialOutputPackage>>=
+)abbrev package SPECOUT SpecialOutputPackage
+++ Author: Stephen M. Watt
+++ Date Created: September 1986
+++ Date Last Updated: May 23, 1991
+++ Basic Operations: outputAsFortran, outputAsScript, outputAsTex
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: SpecialOutputPackage allows FORTRAN, Tex and
+++   Script Formula Formatter output from programs.
+
+SpecialOutputPackage: public == private where
+  public == with
+    outputAsFortran: (String,OutputForm) -> Void
+      ++ outputAsFortran(v,o) sends output v = o in FORTRAN format
+      ++ to the destination defined by \spadsyscom{set output fortran}.
+    outputAsFortran: OutputForm          -> Void
+      ++ outputAsFortran(o) sends output o in FORTRAN format.
+    outputAsScript:  OutputForm          -> Void
+      ++ outputAsScript(o) sends output o in Script Formula Formatter format
+      ++ to the destination defined by \spadsyscom{set output formula}.
+    outputAsTex:     OutputForm          -> Void
+      ++ outputAsTex(o) sends output o in Tex format to the destination
+      ++ defined by \spadsyscom{set output tex}.
+    outputAsFortran: List OutputForm     -> Void
+      ++ outputAsFortran(l) sends (for each expression in the list l)
+      ++ output in FORTRAN format to the destination defined by
+      ++ \spadsyscom{set output fortran}.
+    outputAsScript:  List OutputForm     -> Void
+      ++ outputAsScript(l) sends (for each expression in the list l)
+      ++ output in Script Formula Formatter format to the destination defined.
+      ++ by \spadsyscom{set output forumula}.
+    outputAsTex:     List OutputForm     -> Void
+      ++ outputAsTex(l) sends (for each expression in the list l)
+      ++ output in Tex format to the destination as defined by
+      ++ \spadsyscom{set output tex}.
+
+  private == add
+    e : OutputForm
+    l : List OutputForm
+    var : String
+    --ExpressionPackage()
+
+    juxtaposeTerms: List OutputForm -> OutputForm
+    juxtaposeTerms l == blankSeparate l
+
+    outputAsFortran e ==
+      dispfortexp$Lisp e
+      void()$Void
+
+    outputAsFortran(var,e) ==
+      e := var::Symbol::OutputForm  = e
+      dispfortexp(e)$Lisp
+      void()$Void
+
+    outputAsFortran l ==
+      dispfortexp$Lisp juxtaposeTerms l
+      void()$Void
+
+    outputAsScript e ==
+      formulaFormat$Lisp e
+      void()$Void
+
+    outputAsScript l ==
+      formulaFormat$Lisp juxtaposeTerms l
+      void()$Void
+
+    outputAsTex e ==
+      texFormat$Lisp e
+      void()$Void
+
+    outputAsTex l ==
+      texFormat$Lisp juxtaposeTerms l
+      void()$Void
+
+@
+<<SPECOUT.dotabb>>=
+"SPECOUT" [color="#FF4488",href="bookvol10.4.pdf#nameddest=SPECOUT"]
+"ALIST" [color="#88FF44",href="bookvol10.3.pdf#nameddest=ALIST"]
+"SPECOUT" -> "ALIST"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package MATSTOR StorageEfficientMatrixOperations}
 \pagehead{StorageEfficientMatrixOperations}{MATSTOR}
 \pagepic{ps/v104storageefficientmatrixoperations.ps}{MATSTOR}{1.00}
@@ -58744,6 +61763,254 @@ SupFractionFactorizer(E,OV,R,P) : C == T
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package ODESYS SystemODESolver}
+\pagehead{SystemODESolver}{ODESYS}
+\pagepic{ps/v104systemodesolver.ps}{ODESYS}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package ODESYS SystemODESolver>>=
+)abbrev package ODESYS SystemODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 11 June 1991
+++ Date Last Updated: 13 April 1994
+++ Description: SystemODESolver provides tools for triangulating
+++ and solving some systems of linear ordinary differential equations.
+++ Keywords: differential equation, ODE, system
+SystemODESolver(F, LO): Exports == Implementation where
+  F : Field
+  LO: LinearOrdinaryDifferentialOperatorCategory F
+
+  N   ==> NonNegativeInteger
+  Z   ==> Integer
+  MF  ==> Matrix F
+  M   ==> Matrix LO
+  V   ==> Vector F
+  UF  ==> Union(F, "failed")
+  UV  ==> Union(V, "failed")
+  REC ==> Record(mat: M, vec: V)
+  FSL ==> Record(particular: UF, basis: List F)
+  VSL ==> Record(particular: UV, basis: List V)
+  SOL ==> Record(particular: F, basis: List F)
+  USL ==> Union(SOL, "failed")
+  ER  ==> Record(C: MF, g: V, eq: LO, rh: F)
+
+  Exports ==> with
+    triangulate: (MF, V) -> Record(A:MF, eqs: List ER)
+      ++ triangulate(M,v) returns
+      ++ \spad{A,[[C_1,g_1,L_1,h_1],...,[C_k,g_k,L_k,h_k]]}
+      ++ such that under the change of variable \spad{y = A z}, the first
+      ++ order linear system \spad{D y = M y + v} is uncoupled as
+      ++ \spad{D z_i = C_i z_i + g_i} and each \spad{C_i} is a companion
+      ++ matrix corresponding to the scalar equation \spad{L_i z_j = h_i}.
+    triangulate: (M, V) -> REC
+      ++ triangulate(m, v) returns \spad{[m_0, v_0]} such that \spad{m_0}
+      ++ is upper triangular and the system \spad{m_0 x = v_0} is equivalent
+      ++ to \spad{m x = v}.
+    solve: (MF,V,(LO,F)->USL) -> Union(Record(particular:V, basis:MF),"failed")
+      ++ solve(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such that
+      ++ the solutions in \spad{F} of the system \spad{D x = m x + v} are
+      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+      ++ constants, and the \spad{v_i's} form a basis for the solutions of
+      ++ \spad{D x = m x}.
+      ++ Argument \spad{solve} is a function for solving a single linear
+      ++ ordinary differential equation in \spad{F}.
+    solveInField: (M, V, (LO, F) -> FSL) -> VSL
+      ++ solveInField(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such
+      ++ that the solutions in \spad{F} of the system \spad{m x = v} are
+      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+      ++ constants, and the \spad{v_i's} form a basis for the solutions of
+      ++ \spad{m x = 0}.
+      ++ Argument \spad{solve} is a function for solving a single linear
+      ++ ordinary differential equation in \spad{F}.
+
+  Implementation ==> add
+    import PseudoLinearNormalForm F
+
+    applyLodo   : (M, Z, V, N) -> F
+    applyLodo0  : (M, Z, Matrix F, Z, N) -> F
+    backsolve   : (M, V, (LO, F) -> FSL) -> VSL
+    firstnonzero: (M, Z) -> Z
+    FSL2USL     : FSL -> USL
+    M2F         : M -> Union(MF, "failed")
+
+    diff := D()$LO
+
+    solve(mm, v, solve) ==
+      rec  := triangulate(mm, v)
+      sols:List(SOL) := empty()
+      for e in rec.eqs repeat
+          (u := solve(e.eq, e.rh)) case "failed" => return "failed"
+          sols := concat(u::SOL, sols)
+      n := nrows(rec.A)    -- dimension of original vectorspace
+      k:N := 0             -- sum of sizes of visited companionblocks
+      i:N := 0             -- number of companionblocks
+      m:N := 0             -- number of Solutions
+      part:V := new(n, 0)
+      -- count first the different solutions
+      for sol in sols repeat m := m + count(#1 ^= 0, sol.basis)$List(F)
+      SolMatrix:MF := new(n, m, 0)
+      m := 0
+      for sol in reverse_! sols repeat
+          i := i+1
+          er := rec.eqs.i
+          nn := #(er.g)           -- size of active companionblock
+          for s in sol.basis repeat
+              solVec:V := new(n, 0)
+              -- compute corresponding solution base with recursion (24)
+              solVec(k+1) := s
+              for l in 2..nn repeat solVec(k+l) := diff solVec(k+l-1)
+              m := m+1
+              setColumn!(SolMatrix, m, solVec)
+          -- compute with (24) the corresponding components of the part. sol.
+          part(k+1) := sol.particular
+          for l in 2..nn repeat part(k+l) := diff part(k+l-1) - (er.g)(l-1)
+          k := k+nn
+      -- transform these values back to the original system
+      [rec.A * part, rec.A * SolMatrix]
+
+    triangulate(m:MF, v:V) ==
+      k:N := 0       -- sum of companion-dimensions
+      rat := normalForm(m, 1, - diff #1)
+      l   := companionBlocks(rat.R, rat.Ainv * v)
+      ler:List(ER) := empty()
+      for er in l repeat
+        n := nrows(er.C)         -- dimension of this companion vectorspace
+        op:LO := 0               -- compute homogeneous equation
+        for j in 0..n-1 repeat op := op + monomial((er.C)(n, j + 1), j)
+        op := monomial(1, n) - op
+        sum:V := new(n::N, 0)    -- compute inhomogen Vector (25)
+        for j in 1..n-1 repeat sum(j+1) := diff(sum j) + (er.g) j
+        h0:F := 0                 -- compute inhomogenity (26)
+        for j in 1..n repeat h0 := h0 - (er.C)(n, j) * sum j
+        h0 := h0 + diff(sum n) + (er.g) n
+        ler := concat([er.C, er.g, op, h0], ler)
+        k := k + n
+      [rat.A, ler]
+
+-- like solveInField, but expects a system already triangularized
+    backsolve(m, v, solve) ==
+      part:V
+      r := maxRowIndex m
+      offset := minIndex v - (mr := minRowIndex m)
+      while r >= mr and every?(zero?, row(m, r))$Vector(LO) repeat r := r - 1
+      r < mr => error "backsolve: system has a 0 matrix"
+      (c := firstnonzero(m, r)) ^= maxColIndex m =>
+        error "backsolve: undetermined system"
+      rec := solve(m(r, c), v(r + offset))
+      dim := (r - mr + 1)::N
+      if (part? := ((u := rec.particular) case F)) then
+        part := new(dim, 0)                           -- particular solution
+        part(r + offset) :=  u::F
+-- hom is the basis for the homogeneous solutions, each column is a solution
+      hom:Matrix(F) := new(dim, #(rec.basis), 0)
+      for i in minColIndex hom .. maxColIndex hom for b in rec.basis repeat
+        hom(r, i) := b
+      n:N := 1                 -- number of equations already solved
+      while r > mr repeat
+        r := r - 1
+        c := c - 1
+        firstnonzero(m, r) ^= c => error "backsolve: undetermined system"
+        degree(eq := m(r, c)) > 0 => error "backsolve: pivot of order > 0"
+        a := leadingCoefficient(eq)::F
+        if part? then
+           part(r + offset) := (v(r + offset) - applyLodo(m, r, part, n)) / a
+        for i in minColIndex hom .. maxColIndex hom repeat
+          hom(r, i) := - applyLodo0(m, r, hom, i, n)
+        n := n + 1
+      bas:List(V) := [column(hom,i) for i in minColIndex hom..maxColIndex hom]
+      part? => [part, bas]
+      ["failed", bas]
+
+    solveInField(m, v, solve) ==
+      ((n := nrows m) = ncols m) and
+         ((u := M2F(diagonalMatrix [diff for i in 1..n] - m)) case MF) =>
+             (uu := solve(u::MF, v, FSL2USL solve(#1, #2))) case "failed" =>
+                  ["failed", empty()]
+             rc := uu::Record(particular:V, basis:MF)
+             [rc.particular, [column(rc.basis, i) for i in 1..ncols(rc.basis)]]
+      rec := triangulate(m, v)
+      backsolve(rec.mat, rec.vec, solve)
+
+    M2F m ==
+        mf:MF := new(nrows m, ncols m, 0)
+        for i in minRowIndex m .. maxRowIndex m repeat
+            for j in minColIndex m .. maxColIndex m repeat
+                (u := retractIfCan(m(i, j))@Union(F, "failed")) case "failed" =>
+                     return "failed"
+                mf(i, j) := u::F
+        mf
+
+    FSL2USL rec ==
+        rec.particular case "failed" => "failed"
+        [rec.particular::F, rec.basis]
+
+-- returns the index of the first nonzero entry in row r of m
+    firstnonzero(m, r) ==
+      for c in minColIndex m .. maxColIndex m repeat
+        m(r, c) ^= 0 => return c
+      error "firstnonzero: zero row"
+
+-- computes +/[m(r, i) v(i) for i ranging over the last n columns of m]
+    applyLodo(m, r, v, n) ==
+      ans:F := 0
+      c := maxColIndex m
+      cv := maxIndex v
+      for i in 1..n repeat
+        ans := ans + m(r, c) (v cv)
+        c := c - 1
+        cv := cv - 1
+      ans
+
+-- computes +/[m(r, i) mm(i, c) for i ranging over the last n columns of m]
+    applyLodo0(m, r, mm, c, n) ==
+      ans := 0
+      rr := maxRowIndex mm
+      cc := maxColIndex m
+      for i in 1..n repeat
+        ans := ans + m(r, cc) mm(rr, c)
+        cc := cc - 1
+        rr := rr - 1
+      ans
+
+    triangulate(m:M, v:V) ==
+      x := copy m
+      w := copy v
+      nrows := maxRowIndex x
+      ncols := maxColIndex x
+      minr  := i := minRowIndex x
+      offset := minIndex w - minr
+      for j in minColIndex x .. ncols repeat
+        if i > nrows then leave x
+        rown := minr - 1
+        for k in i .. nrows repeat
+          if (x(k, j) ^= 0) and ((rown = minr - 1) or
+                              degree x(k,j) < degree x(rown,j)) then rown := k
+          rown = minr - 1 => "enuf"
+          x := swapRows_!(x, i, rown)
+          swap_!(w, i + offset, rown + offset)
+        for k in i+1 .. nrows | x(k, j) ^= 0 repeat
+          l := rightLcm(x(i,j), x(k,j))
+          a := rightQuotient(l, x(i, j))
+          b := rightQuotient(l, x(k, j))
+          -- l = a x(i,j) = b x(k,j)
+          for k1 in j+1 .. ncols repeat
+            x(k, k1) :=  a * x(i, k1) - b * x(k, k1)
+          x(k, j) := 0
+          w(k + offset) := a(w(i + offset)) - b(w(k + offset))
+        i := i+1
+      [x, w]
+
+@
+<<ODESYS.dotabb>>=
+"ODESYS" [color="#FF4488",href="bookvol10.4.pdf#nameddest=ODESYS"]
+"IVECTOR" [color="#88FF44",href="bookvol10.3.pdf#nameddest=IVECTOR"]
+"ODESYS" -> "IVECTOR"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{package SYMFUNC SymmetricFunctions}
 \pagehead{SymmetricFunctions}{SYMFUNC}
 \pagepic{ps/v104symmetricfunctions.ps}{SYMFUNC}{1.00}
@@ -61955,6 +65222,224 @@ UnivariatePolynomialCommonDenominator(R, Q, UP): Exports == Impl where
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package OREPCTO UnivariateSkewPolynomialCategoryOps}
+\pagehead{UnivariateSkewPolynomialCategoryOps}{OREPCTO}
+\pagepic{ps/v104univariateskewpolynomialcategoryops.ps}{OREPCTO}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>=
+)abbrev package OREPCTO UnivariateSkewPolynomialCategoryOps
+++ Author: Manuel Bronstein
+++ Date Created: 1 February 1994
+++ Date Last Updated: 1 February 1994
+++ Description:
+++   \spad{UnivariateSkewPolynomialCategoryOps} provides products and
+++    divisions of univariate skew polynomials.
+-- Putting those operations here rather than defaults in OREPCAT allows
+-- OREPCAT to be defined independently of sigma and delta.
+-- MB 2/94
+UnivariateSkewPolynomialCategoryOps(R, C): Exports == Implementation where
+    R: Ring
+    C: UnivariateSkewPolynomialCategory R
+ 
+    N   ==> NonNegativeInteger
+    MOR ==> Automorphism R
+    QUOREM ==> Record(quotient: C, remainder: C)
+ 
+    Exports ==> with
+        times: (C, C, MOR, R -> R) -> C
+           ++ times(p, q, sigma, delta) returns \spad{p * q}.
+           ++ \spad{\sigma} and \spad{\delta} are the maps to use.
+        apply: (C, R, R, MOR, R -> R) -> R
+          ++ apply(p, c, m, sigma, delta) returns \spad{p(m)} where the action
+          ++ is given by \spad{x m = c sigma(m) + delta(m)}.
+        if R has IntegralDomain then
+            monicLeftDivide: (C, C, MOR) -> QUOREM
+                ++ monicLeftDivide(a, b, sigma) returns the pair \spad{[q,r]}
+                ++ such that \spad{a = b*q + r} and the degree of \spad{r} is
+                ++ less than the degree of \spad{b}.
+                ++ \spad{b} must be monic.
+                ++ This process is called ``left division''.
+                ++ \spad{\sigma} is the morphism to use.
+            monicRightDivide: (C, C, MOR) -> QUOREM
+                ++ monicRightDivide(a, b, sigma) returns the pair \spad{[q,r]}
+                ++ such that \spad{a = q*b + r} and the degree of \spad{r} is
+                ++ less than the degree of \spad{b}.
+                ++ \spad{b} must be monic.
+                ++ This process is called ``right division''.
+                ++ \spad{\sigma} is the morphism to use.
+        if R has Field then
+            leftDivide: (C, C, MOR) -> QUOREM
+                ++ leftDivide(a, b, sigma) returns the pair \spad{[q,r]} such
+                ++ that \spad{a = b*q + r} and the degree of \spad{r} is
+                ++ less than the degree of \spad{b}.
+                ++ This process is called ``left division''.
+                ++ \spad{\sigma} is the morphism to use.
+            rightDivide: (C, C, MOR) -> QUOREM
+                ++ rightDivide(a, b, sigma) returns the pair \spad{[q,r]} such
+                ++ that \spad{a = q*b + r} and the degree of \spad{r} is
+                ++ less than the degree of \spad{b}.
+                ++ This process is called ``right division''.
+                ++ \spad{\sigma} is the morphism to use.
+ 
+    Implementation ==> add
+        termPoly:         (R, N, C, MOR, R -> R) -> C
+        localLeftDivide : (C, C, MOR, R) -> QUOREM
+        localRightDivide: (C, C, MOR, R) -> QUOREM
+ 
+        times(x, y, sigma, delta) ==
+          zero? y => 0
+          z:C := 0
+          while x ^= 0 repeat
+            z := z + termPoly(leadingCoefficient x, degree x, y, sigma, delta)
+            x := reductum x
+          z
+ 
+        termPoly(a, n, y, sigma, delta) ==
+          zero? y => 0
+          (u := subtractIfCan(n, 1)) case "failed" => a * y
+          n1 := u::N
+          z:C := 0
+          while y ^= 0 repeat
+            m := degree y
+            b := leadingCoefficient y
+            z := z + termPoly(a, n1, monomial(sigma b, m + 1), sigma, delta)
+                   + termPoly(a, n1, monomial(delta b, m), sigma, delta)
+            y := reductum y
+          z
+ 
+        apply(p, c, x, sigma, delta) ==
+          w:R  := 0
+          xn:R := x
+          for i in 0..degree p repeat
+            w  := w + coefficient(p, i) * xn
+            xn := c * sigma xn + delta xn
+          w
+ 
+        -- localLeftDivide(a, b) returns [q, r] such that a = q b + r
+        -- b1 is the inverse of the leadingCoefficient of b
+        localLeftDivide(a, b, sigma, b1) ==
+            zero? b => error "leftDivide: division by 0"
+            zero? a or
+             (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
+                    [0,a]
+            q  := monomial((sigma**(-m))(b1 * leadingCoefficient a), n::N)
+            qr := localLeftDivide(a - b * q, b, sigma, b1)
+            [q + qr.quotient, qr.remainder]
+ 
+        -- localRightDivide(a, b) returns [q, r] such that a = q b + r
+        -- b1 is the inverse of the leadingCoefficient of b
+        localRightDivide(a, b, sigma, b1) ==
+            zero? b => error "rightDivide: division by 0"
+            zero? a or
+              (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
+                    [0,a]
+            q := monomial(leadingCoefficient(a) * (sigma**n) b1, n::N)
+            qr := localRightDivide(a - q * b, b, sigma, b1)
+            [q + qr.quotient, qr.remainder]
+ 
+        if R has IntegralDomain then
+            monicLeftDivide(a, b, sigma) ==
+                unit?(u := leadingCoefficient b) =>
+                    localLeftDivide(a, b, sigma, recip(u)::R)
+                error "monicLeftDivide: divisor is not monic"
+ 
+            monicRightDivide(a, b, sigma) ==
+                unit?(u := leadingCoefficient b) =>
+                    localRightDivide(a, b, sigma, recip(u)::R)
+                error "monicRightDivide: divisor is not monic"
+ 
+        if R has Field then
+            leftDivide(a, b, sigma) ==
+                localLeftDivide(a, b, sigma, inv leadingCoefficient b)
+ 
+            rightDivide(a, b, sigma) ==
+                localRightDivide(a, b, sigma, inv leadingCoefficient b)
+
+@
+<<OREPCTO.dotabb>>=
+"OREPCTO" [color="#FF4488",href="bookvol10.4.pdf#nameddest=OREPCTO"]
+"OREPCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=OREPCAT"]
+"OREPCTO" -> "OREPCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{package UTSODETL UTSodetools}
+\pagehead{UTSodetools}{UTSODETL}
+\pagepic{ps/v104utsodetools.ps}{UTSODETL}{1.00}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\end{tabular}
+
+<<package UTSODETL UTSodetools>>=
+)abbrev package UTSODETL UTSodetools
+++ Author: Manuel Bronstein
+++ Date Created: 31 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++  \spad{RUTSodetools} provides tools to interface with the series
+++   ODE solver when presented with linear ODEs.
+UTSodetools(F, UP, L, UTS): Exports == Implementation where
+  F  : Ring
+  UP : UnivariatePolynomialCategory F
+  L  : LinearOrdinaryDifferentialOperatorCategory UP
+  UTS: UnivariateTaylorSeriesCategory F
+
+  Exports ==> with
+      UP2UTS:   UP -> UTS
+          ++ UP2UTS(p) converts \spad{p} to a Taylor series.
+      UTS2UP:   (UTS, NonNegativeInteger) -> UP
+          ++ UTS2UP(s, n) converts the first \spad{n} terms of \spad{s}
+          ++ to a univariate polynomial.
+      LODO2FUN: L -> (List UTS -> UTS)
+          ++ LODO2FUN(op) returns the function to pass to the series ODE
+          ++ solver in order to solve \spad{op y = 0}.
+      if F has IntegralDomain then
+          RF2UTS: Fraction UP -> UTS
+              ++ RF2UTS(f) converts \spad{f} to a Taylor series.
+
+  Implementation ==> add
+      fun: (Vector UTS, List UTS) -> UTS
+
+      UP2UTS p ==
+        q := p(monomial(1, 1) + center(0)::UP)
+        +/[monomial(coefficient(q, i), i)$UTS for i in 0..degree q]
+
+      UTS2UP(s, n) ==
+        xmc     := monomial(1, 1)$UP - center(0)::UP
+        xmcn:UP := 1
+        ans:UP  := 0
+        for i in 0..n repeat
+            ans  := ans + coefficient(s, i) * xmcn
+            xmcn := xmc * xmcn
+        ans
+
+      LODO2FUN op ==
+          a := recip(UP2UTS(- leadingCoefficient op))::UTS
+          n := (degree(op) - 1)::NonNegativeInteger
+          v := [a * UP2UTS coefficient(op, i) for i in 0..n]$Vector(UTS)
+          fun(v, #1)
+
+      fun(v, l) ==
+          ans:UTS := 0
+          for b in l for i in 1.. repeat ans := ans + v.i * b
+          ans
+
+      if F has IntegralDomain then
+          RF2UTS f == UP2UTS(numer f) * recip(UP2UTS denom f)::UTS
+
+@
+<<UTSODETL.dotabb>>=
+"UTSODETL" [color="#FF4488",href="bookvol10.4.pdf#nameddest=UTSODETL"]
+"UTSCAT" [color="#4488FF",href="bookvol10.2.pdf#nameddest=UTSCAT"]
+"UTSODETL" -> "UTSCAT"
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Chapter V}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -62197,11 +65682,15 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package ODEPACK AnnaOrdinaryDifferentialEquationPackage>>
 <<package PDEPACK AnnaPartialDifferentialEquationPackage>>
 <<package ANY1 AnyFunctions1>>
+<<package APPLYORE ApplyUnivariateSkewPolynomial>>
 <<package ASSOCEQ AssociatedEquations>>
 <<package PMPRED AttachPredicates>>
 <<package AXSERV AxiomServer>>
 
+<<package BALFACT BalancedFactorisation>>
+<<package BOP1 BasicOperatorFunctions1>>
 <<package BEZOUT BezoutMatrix>>
+<<package BOUNDZRO BoundIntegerRoots>>
 <<package BRILL BrillhartTests>>
 
 <<package CARTEN2 CartesianTensorFunctions2>>
@@ -62211,6 +65700,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package CVMP CoerceVectorMatrixPackage>>
 <<package COMBF CombinatorialFunction>>
 <<package CDEN CommonDenominator>>
+<<package COMMONOP CommonOperators>>
 <<package COMPFACT ComplexFactorization>>
 <<package COMPLEX2 ComplexFunctions2>>
 <<package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation>>
@@ -62219,6 +65709,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package CRFP ComplexRootFindingPackage>>
 <<package CMPLXRT ComplexRootPackage>>
 <<package CTRIGMNP ComplexTrigonometricManipulations>>
+<<package ODECONST ConstantLODE>>
 <<package COORDSYS CoordinateSystems>>
 <<package CRAPACK CRApackage>>
 <<package CYCLES CycleIndicators>>
@@ -62227,6 +65718,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package DFINTTLS DefiniteIntegrationTools>>
 <<package DEGRED DegreeReductionPackage>>
 <<package DLP DiscreteLogarithmPackage>>
+<<package DISPLAY DisplayPackage>>
 <<package DDFACT DistinctDegreeFactorize>>
 <<package DBLRESP DoubleResultantPackage>>
 <<package DRAWCX DrawComplex>>
@@ -62241,6 +65733,8 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package EP EigenPackage>>
 <<package EF ElementaryFunction>>
 <<package DEFINTEF ElementaryFunctionDefiniteIntegration>>
+<<package LODEEF ElementaryFunctionLODESolver>>
+<<package ODEEF ElementaryFunctionODESolver>>
 <<package SIGNEF ElementaryFunctionSign>>
 <<package EFSTRUC ElementaryFunctionStructurePackage>>
 <<package EFULS ElementaryFunctionsUnivariateLaurentSeries>>
@@ -62257,6 +65751,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package ES1 ExpressionSpaceFunctions1>>
 <<package ES2 ExpressionSpaceFunctions2>>
 <<package EXPRODE ExpressionSpaceODESolver>>
+<<package OMEXPR ExpressionToOpenMath>>
 <<package EXPR2UPS ExpressionToUnivariatePowerSeries>>
 <<package E04AGNT e04AgentsPackage>>
 
@@ -62432,6 +65927,7 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package NORMMA NormInMonogenicAlgebra>>
 <<package NPCOEF NPCoef>>
 <<package NFINTBAS NumberFieldIntegralBasis>>
+<<package NUMFMT NumberFormats>>
 <<package NUMERIC Numeric>>
 <<package NUMODE NumericalOrdinaryDifferentialEquations>>
 <<package NUMQUAD NumericalQuadrature>>
@@ -62439,11 +65935,17 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package NCNTFRAC NumericContinuedFraction>>
 <<package NREP NumericRealEigenPackage>>
 
+<<package OCTCT2 OctonionCategoryFunctions2>>
+<<package ODEINT ODEIntegration>>
+<<package ODETOOLS ODETools>>
 <<package ARRAY12 OneDimensionalArrayFunctions2>>
 <<package ONECOMP2 OnePointCompletionFunctions2>>
+<<package OMPKG OpenMathPackage>>
+<<package OMSERVER OpenMathServerPackage>>
 <<package ORDCOMP2 OrderedCompletionFunctions2>>
 <<package ORDFUNS OrderingFunctions>>
 <<package OPQUERY OperationsQuery>>
+<<package OUT OutputPackage>>
 
 <<package PMASS PatternMatchAssertions>>
 <<package INTPM PatternMatchIntegration>>
@@ -62457,7 +65959,9 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package LIMITPS PowerSeriesLimitPackage>>
 <<package PREASSOC PrecomputedAssociatedEquations>>
 <<package PRIMARR2 PrimitiveArrayFunctions2>>
+<<package ODEPRIM PrimitiveRatDE>>
 <<package INTPAF PureAlgebraicIntegration>>
+<<package ODEPAL PureAlgebraicLODE>>
 <<package PUSHVAR PushVariables>>
 
 <<package QFCAT2 QuotientFieldCategoryFunctions2>>
@@ -62467,8 +65971,11 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package RFFACTOR RationalFunctionFactorizer>>
 <<package INTRF RationalFunctionIntegration>>
 <<package INTRAT RationalIntegration>>
+<<package ODERAT RationalLODE>>
 <<package REALSOLV RealSolvePackage>>
 <<package RMCAT2 RectangularMatrixCategoryFunctions2>>
+<<package ODERED ReduceLODE>>
+<<package REDORDER ReductionOfOrder>>
 <<package REPDB RepeatedDoubling>>
 <<package REPSQ RepeatedSquaring>>
 <<package RETSOL RetractSolvePackage>>
@@ -62478,11 +65985,13 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package SAEFACT SimpleAlgebraicExtensionAlgFactor>>
 <<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>
 <<package SCACHE SortedCache>>
+<<package SPECOUT SpecialOutputPackage>>
 <<package MATSTOR StorageEfficientMatrixOperations>>
 <<package STINPROD StreamInfiniteProduct>>
 <<package SCPKG StructuralConstantsPackage>>
 <<package SUBRESP SubResultantPackage>>
 <<package SUPFRACF SupFractionFactorizer>>
+<<package ODESYS SystemODESolver>>
 <<package SYMFUNC SymmetricFunctions>>
 
 <<package TBCMPPK TabulatedComputationPackage>>
@@ -62502,6 +66011,8 @@ WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
 <<package UFPS1 UnivariateFormalPowerSeriesFunctions>>
 <<package ULS2 UnivariateLaurentSeriesFunctions2>>
 <<package UPCDEN UnivariatePolynomialCommonDenominator>>
+<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>
+<<package UTSODETL UTSodetools>>
 
 <<package WFFINTBS WildFunctionFieldIntegralBasis>>
 
diff --git a/books/ps/v104applyunivariateskewpolynomial.ps b/books/ps/v104applyunivariateskewpolynomial.ps
new file mode 100644
index 0000000..6b02edb
--- /dev/null
+++ b/books/ps/v104applyunivariateskewpolynomial.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
+% APPLYORE
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=APPLYORE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 70 (APPLYORE) alignedtext
+grestore
+% OREPCAT
+gsave
+[ /Rect [ 4 0 82 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OREPCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+82 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+82 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 63 (OREPCAT) alignedtext
+grestore
+% APPLYORE->OREPCAT
+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/v104balancedfactorisation.ps b/books/ps/v104balancedfactorisation.ps
new file mode 100644
index 0000000..4ac0dab
--- /dev/null
+++ b/books/ps/v104balancedfactorisation.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
+% BALFACT
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=BALFACT) >>
+  /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 (BALFACT) 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
+% BALFACT->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/v104basicoperatorfunctions1.ps b/books/ps/v104basicoperatorfunctions1.ps
new file mode 100644
index 0000000..8498603
--- /dev/null
+++ b/books/ps/v104basicoperatorfunctions1.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
+% BOP1
+gsave
+[ /Rect [ 0 72 54 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=BOP1) >>
+  /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
+10 85.9 moveto 34 (BOP1) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 0 0 54 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 54 36 moveto
+1.41189e-14 36 lineto
+3.65506e-15 1.06581e-14 lineto
+54 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 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 (ALIST) alignedtext
+grestore
+% BOP1->ALIST
+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/v104boundintegerroots.ps b/books/ps/v104boundintegerroots.ps
new file mode 100644
index 0000000..086b5f2
--- /dev/null
+++ b/books/ps/v104boundintegerroots.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 136 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 100 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
+% BOUNDZRO
+gsave
+[ /Rect [ 0 72 92 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=BOUNDZRO) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.76723e-14 108 lineto
+6.58501e-15 72 lineto
+92 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.76723e-14 108 lineto
+6.58501e-15 72 lineto
+92 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 77 (BOUNDZRO) alignedtext
+grestore
+% PFECAT
+gsave
+[ /Rect [ 13 0 79 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 79 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+79 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 79 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+79 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20.5 13.9 moveto 51 (PFECAT) alignedtext
+grestore
+% BOUNDZRO->PFECAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 46 72 moveto
+46 64 46 55 46 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 136 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104commonoperators.ps b/books/ps/v104commonoperators.ps
new file mode 100644
index 0000000..348f8a4
--- /dev/null
+++ b/books/ps/v104commonoperators.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 144 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 108 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
+% COMMONOP
+gsave
+[ /Rect [ 0 72 100 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=COMMONOP) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 100 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+100 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 100 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+100 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 84 (COMMONOP) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 23 0 77 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 77 36 moveto
+23 36 lineto
+23 1.06581e-14 lineto
+77 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 77 36 moveto
+23 36 lineto
+23 1.06581e-14 lineto
+77 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+30.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% COMMONOP->ALIST
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 50 72 moveto
+50 64 50 55 50 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 53.5001 46 moveto
+50 36 lineto
+46.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 53.5001 46 moveto
+50 36 lineto
+46.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 144 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104constantlode.ps b/books/ps/v104constantlode.ps
new file mode 100644
index 0000000..16284d5
--- /dev/null
+++ b/books/ps/v104constantlode.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 136 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 100 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
+% ODECONST
+gsave
+[ /Rect [ 0 72 92 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODECONST) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+92 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+92 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 76 (ODECONST) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 19 0 73 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+19 36 lineto
+19 1.06581e-14 lineto
+73 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 73 36 moveto
+19 36 lineto
+19 1.06581e-14 lineto
+73 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+28.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% ODECONST->ACFS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 46 72 moveto
+46 64 46 55 46 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 136 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104displaypackage.ps b/books/ps/v104displaypackage.ps
new file mode 100644
index 0000000..be451a1
--- /dev/null
+++ b/books/ps/v104displaypackage.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
+% DISPLAY
+gsave
+[ /Rect [ 0 72 72 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=DISPLAY) >>
+  /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 (DISPLAY) alignedtext
+grestore
+% STRING
+gsave
+[ /Rect [ 3 0 69 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=STRING) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 69 36 moveto
+3 36 lineto
+3 1.06581e-14 lineto
+69 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 69 36 moveto
+3 36 lineto
+3 1.06581e-14 lineto
+69 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11 13.9 moveto 50 (STRING) alignedtext
+grestore
+% DISPLAY->STRING
+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/v104elementaryfunctionlodesolver.ps b/books/ps/v104elementaryfunctionlodesolver.ps
new file mode 100644
index 0000000..9eeec5d
--- /dev/null
+++ b/books/ps/v104elementaryfunctionlodesolver.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
+% LODEEF
+gsave
+[ /Rect [ 0 72 70 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=LODEEF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+70 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 70 108 moveto
+2.13163e-14 108 lineto
+7.10543e-15 72 lineto
+70 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 54 (LODEEF) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 8 0 62 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+17.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% LODEEF->ACFS
+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/v104elementaryfunctionodesolver.ps b/books/ps/v104elementaryfunctionodesolver.ps
new file mode 100644
index 0000000..d3eb565
--- /dev/null
+++ b/books/ps/v104elementaryfunctionodesolver.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
+% ODEEF
+gsave
+[ /Rect [ 0 72 62 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODEEF) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+62 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 62 108 moveto
+2.13163e-14 108 lineto
+3.55271e-15 72 lineto
+62 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 46 (ODEEF) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 4 0 58 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+58 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 58 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+58 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% ODEEF->ACFS
+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/v104expressiontoopenmath.ps b/books/ps/v104expressiontoopenmath.ps
new file mode 100644
index 0000000..491210c
--- /dev/null
+++ b/books/ps/v104expressiontoopenmath.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
+% OMEXPR
+gsave
+[ /Rect [ 0 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=OMEXPR) >>
+  /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 (OMEXPR) alignedtext
+grestore
+% FS
+gsave
+[ /Rect [ 10 0 64 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 64 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+64 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 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
+29.5 13.9 moveto 15 (FS) alignedtext
+grestore
+% OMEXPR->FS
+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/v104numberformats.ps b/books/ps/v104numberformats.ps
new file mode 100644
index 0000000..07bd3dc
--- /dev/null
+++ b/books/ps/v104numberformats.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
+% NUMFMT
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=NUMFMT) >>
+  /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 (NUMFMT) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 12 0 66 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 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 66 36 moveto
+12 36 lineto
+12 1.06581e-14 lineto
+66 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+19.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% NUMFMT->ALIST
+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/v104octonioncategoryfunctions2.ps b/books/ps/v104octonioncategoryfunctions2.ps
new file mode 100644
index 0000000..da656ce
--- /dev/null
+++ b/books/ps/v104octonioncategoryfunctions2.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
+% OCTCT2
+gsave
+[ /Rect [ 0 72 70 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=OCTCT2) >>
+  /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 (OCTCT2) alignedtext
+grestore
+% OC
+gsave
+[ /Rect [ 8 0 62 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OC) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 62 36 moveto
+8 36 lineto
+8 1.06581e-14 lineto
+62 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+25 13.9 moveto 20 (OC) alignedtext
+grestore
+% OCTCT2->OC
+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/v104odeintegration.ps b/books/ps/v104odeintegration.ps
new file mode 100644
index 0000000..91d5db8
--- /dev/null
+++ b/books/ps/v104odeintegration.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 112 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 76 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ODEINT
+gsave
+[ /Rect [ 0 72 68 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODEINT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 53 (ODEINT) alignedtext
+grestore
+% ACFS
+gsave
+[ /Rect [ 7 0 61 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ACFS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 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 61 36 moveto
+7 36 lineto
+7 1.06581e-14 lineto
+61 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+16.5 13.9 moveto 35 (ACFS) alignedtext
+grestore
+% ODEINT->ACFS
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 112 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104odetools.ps b/books/ps/v104odetools.ps
new file mode 100644
index 0000000..8c7cae4
--- /dev/null
+++ b/books/ps/v104odetools.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
+% ODETOOLS
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODETOOLS) >>
+  /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 (ODETOOLS) alignedtext
+grestore
+% IVECTOR
+gsave
+[ /Rect [ 6 0 84 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 84 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+84 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 84 36 moveto
+6 36 lineto
+6 1.06581e-14 lineto
+84 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+14 13.9 moveto 62 (IVECTOR) alignedtext
+grestore
+% ODETOOLS->IVECTOR
+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/v104openmathpackage.ps b/books/ps/v104openmathpackage.ps
new file mode 100644
index 0000000..b0ef2cf
--- /dev/null
+++ b/books/ps/v104openmathpackage.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
+% OMPKG
+gsave
+[ /Rect [ 0 72 66 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=OMPKG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+2.24404e-14 108 lineto
+8.44116e-15 72 lineto
+66 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 66 108 moveto
+2.24404e-14 108 lineto
+8.44116e-15 72 lineto
+66 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 51 (OMPKG) alignedtext
+grestore
+% STRING
+gsave
+[ /Rect [ 0 0 66 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=STRING) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 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.273 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 (STRING) alignedtext
+grestore
+% OMPKG->STRING
+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/v104openmathserverpackage.ps b/books/ps/v104openmathserverpackage.ps
new file mode 100644
index 0000000..ea1aaf7
--- /dev/null
+++ b/books/ps/v104openmathserverpackage.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 136 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 100 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
+% OMSERVER
+gsave
+[ /Rect [ 0 72 92 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=OMSERVER) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+92 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 92 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+92 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 76 (OMSERVER) alignedtext
+grestore
+% STRING
+gsave
+[ /Rect [ 13 0 79 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=STRING) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 79 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+79 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 79 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+79 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+21 13.9 moveto 50 (STRING) alignedtext
+grestore
+% OMSERVER->STRING
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 46 72 moveto
+46 64 46 55 46 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 49.5001 46 moveto
+46 36 lineto
+42.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 136 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104outputpackage.ps b/books/ps/v104outputpackage.ps
new file mode 100644
index 0000000..883bfbc
--- /dev/null
+++ b/books/ps/v104outputpackage.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
+% OUT
+gsave
+[ /Rect [ 6 72 60 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=OUT) >>
+  /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
+18 85.9 moveto 30 (OUT) 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
+% OUT->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/v104primitiveratde.ps b/books/ps/v104primitiveratde.ps
new file mode 100644
index 0000000..1679aaf
--- /dev/null
+++ b/books/ps/v104primitiveratde.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
+% ODEPRIM
+gsave
+[ /Rect [ 0 72 78 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODEPRIM) >>
+  /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 (ODEPRIM) 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
+% ODEPRIM->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/v104purealgebraiclode.ps b/books/ps/v104purealgebraiclode.ps
new file mode 100644
index 0000000..f021c2e
--- /dev/null
+++ b/books/ps/v104purealgebraiclode.ps
@@ -0,0 +1,281 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 112 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 76 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% ODEPAL
+gsave
+[ /Rect [ 0 72 68 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODEPAL) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 68 108 moveto
+1.93977e-14 108 lineto
+5.39152e-15 72 lineto
+68 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 85.9 moveto 53 (ODEPAL) alignedtext
+grestore
+% FFCAT
+gsave
+[ /Rect [ 5 0 63 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 63 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+63 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 63 36 moveto
+5 36 lineto
+5 1.06581e-14 lineto
+63 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+13 13.9 moveto 42 (FFCAT) alignedtext
+grestore
+% ODEPAL->FFCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 34 72 moveto
+34 64 34 55 34 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 37.5001 46 moveto
+34 36 lineto
+30.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 112 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104rationallode.ps b/books/ps/v104rationallode.ps
new file mode 100644
index 0000000..1cf29a9
--- /dev/null
+++ b/books/ps/v104rationallode.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
+% ODERAT
+gsave
+[ /Rect [ 0 72 72 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODERAT) >>
+  /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 (ODERAT) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 9 0 63 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 63 36 moveto
+9 36 lineto
+9 1.06581e-14 lineto
+63 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 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 (ALIST) alignedtext
+grestore
+% ODERAT->ALIST
+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/v104reducelode.ps b/books/ps/v104reducelode.ps
new file mode 100644
index 0000000..d5c9862
--- /dev/null
+++ b/books/ps/v104reducelode.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
+% ODERED
+gsave
+[ /Rect [ 8 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODERED) >>
+  /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 (ODERED) 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
+% ODERED->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/v104reductionoforder.ps b/books/ps/v104reductionoforder.ps
new file mode 100644
index 0000000..d53809a
--- /dev/null
+++ b/books/ps/v104reductionoforder.ps
@@ -0,0 +1,326 @@
+%!PS-Adobe-2.0
+%%Creator: Graphviz version 2.16.1 (Mon Jul  7 18:20:33 UTC 2008)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: (atend)
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+       dup 1 exch div /InvScaleFactor exch def
+       scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw text fitted to its expected width
+/alignedtext {			% width text
+	/text exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			[] 0 setdash
+			text stringwidth pop width exch sub text length div 0 text ashow
+		} if
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+setupLatin1
+%%Page: 1 1
+%%PageBoundingBox: 36 36 202 152
+%%PageOrientation: Portrait
+0 0 1 beginpage
+gsave
+36 36 166 116 boxprim clip newpath
+1 1 set_scale 0 rotate 40 40 translate
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath fill
+1 setlinewidth
+0.167 0.600 1.000 graphcolor
+newpath -4 -4 moveto
+-4 716 lineto
+536 716 lineto
+536 -4 lineto
+closepath stroke
+% REDORDER
+gsave
+[ /Rect [ 38 72 128 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=REDORDER) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 128 108 moveto
+38 108 lineto
+38 72 lineto
+128 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 128 108 moveto
+38 108 lineto
+38 72 lineto
+128 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+45.5 85.9 moveto 75 (REDORDER) alignedtext
+grestore
+% OREPCAT
+gsave
+[ /Rect [ 0 0 78 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OREPCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 78 36 moveto
+2.634e-14 36 lineto
+5.29438e-15 1.06581e-14 lineto
+78 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+7.5 13.9 moveto 63 (OREPCAT) alignedtext
+grestore
+% REDORDER->OREPCAT
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 72 72 moveto
+67 64 61 54 55 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 57.916 43.0418 moveto
+50 36 lineto
+51.7969 46.4414 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 57.916 43.0418 moveto
+50 36 lineto
+51.7969 46.4414 lineto
+closepath stroke
+grestore
+% A1AGG
+gsave
+[ /Rect [ 96 0 158 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=A1AGG) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+158 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 158 36 moveto
+96 36 lineto
+96 1.06581e-14 lineto
+158 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+103.5 13.9 moveto 47 (A1AGG) alignedtext
+grestore
+% REDORDER->A1AGG
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 94 72 moveto
+99 64 105 54 111 45 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 114.203 46.4414 moveto
+116 36 lineto
+108.084 43.0418 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 114.203 46.4414 moveto
+116 36 lineto
+108.084 43.0418 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 202 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104specialoutputpackage.ps b/books/ps/v104specialoutputpackage.ps
new file mode 100644
index 0000000..03dac8d
--- /dev/null
+++ b/books/ps/v104specialoutputpackage.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
+% SPECOUT
+gsave
+[ /Rect [ 0 72 80 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=SPECOUT) >>
+  /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 (SPECOUT) alignedtext
+grestore
+% ALIST
+gsave
+[ /Rect [ 13 0 67 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.3.pdf#nameddest=ALIST) >>
+  /Subtype /Link
+/ANN pdfmark
+0.273 0.733 1.000 nodecolor
+newpath 67 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+67 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.273 0.733 1.000 nodecolor
+newpath 67 36 moveto
+13 36 lineto
+13 1.06581e-14 lineto
+67 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+20.5 13.9 moveto 39 (ALIST) alignedtext
+grestore
+% SPECOUT->ALIST
+gsave
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 40 72 moveto
+40 64 40 55 40 46 curveto
+stroke
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath fill
+1 setlinewidth
+solid
+0.000 0.000 0.000 edgecolor
+newpath 43.5001 46 moveto
+40 36 lineto
+36.5001 46 lineto
+closepath stroke
+grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+%%BoundingBox: 36 36 124 152
+end
+restore
+%%EOF
diff --git a/books/ps/v104systemodesolver.ps b/books/ps/v104systemodesolver.ps
new file mode 100644
index 0000000..11a133c
--- /dev/null
+++ b/books/ps/v104systemodesolver.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
+% ODESYS
+gsave
+[ /Rect [ 4 72 74 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=ODESYS) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+4 108 lineto
+4 72 lineto
+74 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 74 108 moveto
+4 108 lineto
+4 72 lineto
+74 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+12 85.9 moveto 54 (ODESYS) 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
+% ODESYS->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/v104univariateskewpolynomialcategoryops.ps b/books/ps/v104univariateskewpolynomialcategoryops.ps
new file mode 100644
index 0000000..6b02edb
--- /dev/null
+++ b/books/ps/v104univariateskewpolynomialcategoryops.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
+% APPLYORE
+gsave
+[ /Rect [ 0 72 86 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=APPLYORE) >>
+  /Subtype /Link
+/ANN pdfmark
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+86 72 lineto
+closepath fill
+1 setlinewidth
+filled
+0.939 0.733 1.000 nodecolor
+newpath 86 108 moveto
+2.84217e-14 108 lineto
+7.10543e-15 72 lineto
+86 72 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+8 85.9 moveto 70 (APPLYORE) alignedtext
+grestore
+% OREPCAT
+gsave
+[ /Rect [ 4 0 82 36 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=OREPCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+82 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 82 36 moveto
+4 36 lineto
+4 1.06581e-14 lineto
+82 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+11.5 13.9 moveto 63 (OREPCAT) alignedtext
+grestore
+% APPLYORE->OREPCAT
+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/v104utsodetools.ps b/books/ps/v104utsodetools.ps
new file mode 100644
index 0000000..0f5e350
--- /dev/null
+++ b/books/ps/v104utsodetools.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
+% UTSODETL
+gsave
+[ /Rect [ 0 72 90 108 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.4.pdf#nameddest=UTSODETL) >>
+  /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 (UTSODETL) alignedtext
+grestore
+% UTSCAT
+gsave
+[ /Rect [ 10 0 80 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 80 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+80 0 lineto
+closepath fill
+1 setlinewidth
+filled
+0.606 0.733 1.000 nodecolor
+newpath 80 36 moveto
+10 36 lineto
+10 1.06581e-14 lineto
+80 0 lineto
+closepath stroke
+0.000 0.000 0.000 nodecolor
+14.00 /Times-Roman set_font
+18 13.9 moveto 54 (UTSCAT) alignedtext
+grestore
+% UTSODETL->UTSCAT
+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/changelog b/changelog
index 5264222..6290590 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,44 @@
+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
+20090207 tpd src/algebra/out.spad removed
+20090207 tpd books/ps/v104displaypackage.ps added
+20090207 tpd books/ps/v104specialoutputpackage.ps added
+20090207 tpd books/ps/v104outputpackage.ps added
+20090207 tpd src/algebra/outform.spad removed
+20090207 tpd books/ps/v104numberformats.ps added
+20090207 tpd src/algebra/ore.spad removed
+20090207 tpd books/ps/v104univariateskewpolynomialcategoryops.ps added
+20090207 tpd books/ps/v104applyunivariateskewpolynomial.ps added
+20090207 tpd src/algebra/op.spad removed
+20090207 tpd books/ps/v104commonoperators.ps added
+20090207 tpd books/ps/v104basicoperatorfunctions1.ps added
+20090207 tpd src/algebra/openmath.spad removed
+20090207 tpd books/ps/v104expressiontoopenmath.ps added
+20090207 tpd src/algebra/omserver.spad removed
+20090207 tpd books/ps/v104openmathserverpackage.ps added
+20090207 tpd src/algebra/omdev.spad removed
+20090207 tpd books/ps/v104openmathpackage.ps added
+20090207 tpd src/algebra/oderf.spad removed
+20090207 tpd books/ps/v104constantlode.ps added
+20090207 tpd books/ps/v104odeintegration.ps added
+20090207 tpd books/ps/v104odetools.ps added
+20090207 tpd books/ps/v104rationallode.ps added
+20090207 tpd books/ps/v104utsodetools.ps added
+20090207 tpd books/ps/v104primitiveratde.ps added
+20090207 tpd books/ps/v104primitivearrayfunctions2.ps added
+20090207 tpd books/ps/v104boundintegerroots.ps added
+20090207 tpd books/ps/v104balancedfactorisation.ps added
+20090207 tpd src/algebra/odeef.spad removed
+20090207 tpd books/ps/v104elementaryfunctionodesolver.ps added
+20090207 tpd books/ps/v104elementaryfunctionlodesolver.ps added
+20090207 tpd books/ps/v104reductionoforder.ps added
+20090207 tpd src/algebra/odealg.spad removed
+20090207 tpd books/ps/v104purealgebraiclode.ps added
+20090207 tpd books/ps/v104reducelode.ps added
+20090207 tpd books/ps/v104systemodesolver.ps added
+20090207 tpd src/algebra/oct.spad removed
+20090207 tpd books/ps/v104octonioncategoryfunctions2.ps added
 20090207 tpd src/axiom-website/patches.html 20090207.01.tpd.patch
 20090207 tpd src/algebra/Makefile remove spad files
 20090207 tpd src/algebra/numtheor.spad removed
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 9f9942e..af382cc 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -15771,11 +15771,6 @@ We need to figure out which mlift.spad to keep.
 <<environment>>=
 
 SPADFILES= \
- ${OUTSRC}/oct.spad ${OUTSRC}/odealg.spad ${OUTSRC}/odeef.spad \
- ${OUTSRC}/oderf.spad ${OUTSRC}/omdev.spad \
- ${OUTSRC}/omserver.spad \
- ${OUTSRC}/openmath.spad ${OUTSRC}/op.spad ${OUTSRC}/ore.spad \
- ${OUTSRC}/outform.spad ${OUTSRC}/out.spad \
  ${OUTSRC}/pade.spad ${OUTSRC}/padiclib.spad \
  ${OUTSRC}/paramete.spad ${OUTSRC}/partperm.spad ${OUTSRC}/patmatch1.spad \
  ${OUTSRC}/patmatch2.spad ${OUTSRC}/pattern.spad \
@@ -15852,11 +15847,6 @@ DOCFILES= \
  ${DOC}/nepip.as.dvi  \
  ${DOC}/noptip.as.dvi ${DOC}/nqip.as.dvi \
  ${DOC}/nrc.as.dvi  ${DOC}/nsfip.as.dvi \
- ${DOC}/oct.spad.dvi ${DOC}/odealg.spad.dvi ${DOC}/odeef.spad.dvi \
- ${DOC}/oderf.spad.dvi ${DOC}/omdev.spad.dvi \
- ${DOC}/omserver.spad.dvi \
- ${DOC}/openmath.spad.dvi ${DOC}/op.spad.dvi ${DOC}/ore.spad.dvi \
- ${DOC}/outform.spad.dvi ${DOC}/out.spad.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 \
diff --git a/src/algebra/oct.spad.pamphlet b/src/algebra/oct.spad.pamphlet
deleted file mode 100644
index a5383c0..0000000
--- a/src/algebra/oct.spad.pamphlet
+++ /dev/null
@@ -1,90 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\usepackage{pstricks, pst-node}
-\begin{document}
-\title{\$SPAD/src/algebra oct.spad}
-\author{Robert Wisbauer, Johannes Grabmeier}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package OCTCT2 OctonionCategoryFunctions2}
-<<package OCTCT2 OctonionCategoryFunctions2>>=
-)abbrev package OCTCT2 OctonionCategoryFunctions2
---% OctonionCategoryFunctions2
-++ Author: Johannes Grabmeier
-++ Date Created: 10 September 1990
-++ Date Last Updated: 10 September 1990
-++ Basic Operations: map
-++ Related Constructors: 
-++ Also See: 
-++ AMS Classifications:
-++ Keywords: octonion, non-associative algebra, Cayley-Dixon  
-++ References:
-++ Description:
-++  OctonionCategoryFunctions2 implements functions between
-++  two octonion domains defined over different rings. 
-++  The function map is used 
-++  to coerce between octonion types.
- 
-OctonionCategoryFunctions2(OR,R,OS,S) : Exports ==
-  Implementation where
-    R  : CommutativeRing
-    S  : CommutativeRing
-    OR : OctonionCategory R
-    OS : OctonionCategory S
-    Exports == with
-      map:     (R -> S, OR) -> OS
-        ++ map(f,u) maps f onto the component parts of the octonion
-        ++ u.
-    Implementation == add
-      map(fn : R -> S, u : OR): OS ==
-        octon(fn real u, fn imagi u, fn imagj u, fn imagk u,_
-        fn imagE u, fn imagI u, fn imagJ u, fn imagK u)$OS
-
-@
-\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 OCTCT2 OctonionCategoryFunctions2>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/odealg.spad.pamphlet b/src/algebra/odealg.spad.pamphlet
deleted file mode 100644
index 29a358d..0000000
--- a/src/algebra/odealg.spad.pamphlet
+++ /dev/null
@@ -1,393 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra odealg.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package ODESYS SystemODESolver}
-<<package ODESYS SystemODESolver>>=
-)abbrev package ODESYS SystemODESolver
-++ Author: Manuel Bronstein
-++ Date Created: 11 June 1991
-++ Date Last Updated: 13 April 1994
-++ Description: SystemODESolver provides tools for triangulating
-++ and solving some systems of linear ordinary differential equations.
-++ Keywords: differential equation, ODE, system
-SystemODESolver(F, LO): Exports == Implementation where
-  F : Field
-  LO: LinearOrdinaryDifferentialOperatorCategory F
-
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  MF  ==> Matrix F
-  M   ==> Matrix LO
-  V   ==> Vector F
-  UF  ==> Union(F, "failed")
-  UV  ==> Union(V, "failed")
-  REC ==> Record(mat: M, vec: V)
-  FSL ==> Record(particular: UF, basis: List F)
-  VSL ==> Record(particular: UV, basis: List V)
-  SOL ==> Record(particular: F, basis: List F)
-  USL ==> Union(SOL, "failed")
-  ER  ==> Record(C: MF, g: V, eq: LO, rh: F)
-
-  Exports ==> with
-    triangulate: (MF, V) -> Record(A:MF, eqs: List ER)
-      ++ triangulate(M,v) returns
-      ++ \spad{A,[[C_1,g_1,L_1,h_1],...,[C_k,g_k,L_k,h_k]]}
-      ++ such that under the change of variable \spad{y = A z}, the first
-      ++ order linear system \spad{D y = M y + v} is uncoupled as
-      ++ \spad{D z_i = C_i z_i + g_i} and each \spad{C_i} is a companion
-      ++ matrix corresponding to the scalar equation \spad{L_i z_j = h_i}.
-    triangulate: (M, V) -> REC
-      ++ triangulate(m, v) returns \spad{[m_0, v_0]} such that \spad{m_0}
-      ++ is upper triangular and the system \spad{m_0 x = v_0} is equivalent
-      ++ to \spad{m x = v}.
-    solve: (MF,V,(LO,F)->USL) -> Union(Record(particular:V, basis:MF), "failed")
-      ++ solve(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such that
-      ++ the solutions in \spad{F} of the system \spad{D x = m x + v} are
-      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
-      ++ constants, and the \spad{v_i's} form a basis for the solutions of
-      ++ \spad{D x = m x}.
-      ++ Argument \spad{solve} is a function for solving a single linear
-      ++ ordinary differential equation in \spad{F}.
-    solveInField: (M, V, (LO, F) -> FSL) -> VSL
-      ++ solveInField(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such that
-      ++ the solutions in \spad{F} of the system \spad{m x = v} are
-      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
-      ++ constants, and the \spad{v_i's} form a basis for the solutions of
-      ++ \spad{m x = 0}.
-      ++ Argument \spad{solve} is a function for solving a single linear
-      ++ ordinary differential equation in \spad{F}.
-
-  Implementation ==> add
-    import PseudoLinearNormalForm F
-
-    applyLodo   : (M, Z, V, N) -> F
-    applyLodo0  : (M, Z, Matrix F, Z, N) -> F
-    backsolve   : (M, V, (LO, F) -> FSL) -> VSL
-    firstnonzero: (M, Z) -> Z
-    FSL2USL     : FSL -> USL
-    M2F         : M -> Union(MF, "failed")
-
-    diff := D()$LO
-
-    solve(mm, v, solve) ==
-      rec  := triangulate(mm, v)
-      sols:List(SOL) := empty()
-      for e in rec.eqs repeat
-          (u := solve(e.eq, e.rh)) case "failed" => return "failed"
-          sols := concat(u::SOL, sols)
-      n := nrows(rec.A)    -- dimension of original vectorspace
-      k:N := 0             -- sum of sizes of visited companionblocks
-      i:N := 0             -- number of companionblocks
-      m:N := 0             -- number of Solutions
-      part:V := new(n, 0)
-      -- count first the different solutions
-      for sol in sols repeat m := m + count(#1 ^= 0, sol.basis)$List(F)
-      SolMatrix:MF := new(n, m, 0)
-      m := 0
-      for sol in reverse_! sols repeat
-          i := i+1
-          er := rec.eqs.i
-          nn := #(er.g)           -- size of active companionblock
-          for s in sol.basis repeat
-              solVec:V := new(n, 0)
-              -- compute corresponding solution base with recursion (24)
-              solVec(k+1) := s
-              for l in 2..nn repeat solVec(k+l) := diff solVec(k+l-1)
-              m := m+1
-              setColumn!(SolMatrix, m, solVec)
-          -- compute with (24) the corresponding components of the part. sol.
-          part(k+1) := sol.particular
-          for l in 2..nn repeat part(k+l) := diff part(k+l-1) - (er.g)(l-1)
-          k := k+nn
-      -- transform these values back to the original system
-      [rec.A * part, rec.A * SolMatrix]
-
-    triangulate(m:MF, v:V) ==
-      k:N := 0       -- sum of companion-dimensions
-      rat := normalForm(m, 1, - diff #1)
-      l   := companionBlocks(rat.R, rat.Ainv * v)
-      ler:List(ER) := empty()
-      for er in l repeat
-        n := nrows(er.C)         -- dimension of this companion vectorspace
-        op:LO := 0               -- compute homogeneous equation
-        for j in 0..n-1 repeat op := op + monomial((er.C)(n, j + 1), j)
-        op := monomial(1, n) - op
-        sum:V := new(n::N, 0)    -- compute inhomogen Vector (25)
-        for j in 1..n-1 repeat sum(j+1) := diff(sum j) + (er.g) j
-        h0:F := 0                 -- compute inhomogenity (26)
-        for j in 1..n repeat h0 := h0 - (er.C)(n, j) * sum j
-        h0 := h0 + diff(sum n) + (er.g) n
-        ler := concat([er.C, er.g, op, h0], ler)
-        k := k + n
-      [rat.A, ler]
-
--- like solveInField, but expects a system already triangularized
-    backsolve(m, v, solve) ==
-      part:V
-      r := maxRowIndex m
-      offset := minIndex v - (mr := minRowIndex m)
-      while r >= mr and every?(zero?, row(m, r))$Vector(LO) repeat r := r - 1
-      r < mr => error "backsolve: system has a 0 matrix"
-      (c := firstnonzero(m, r)) ^= maxColIndex m =>
-        error "backsolve: undetermined system"
-      rec := solve(m(r, c), v(r + offset))
-      dim := (r - mr + 1)::N
-      if (part? := ((u := rec.particular) case F)) then
-        part := new(dim, 0)                           -- particular solution
-        part(r + offset) :=  u::F
--- hom is the basis for the homogeneous solutions, each column is a solution
-      hom:Matrix(F) := new(dim, #(rec.basis), 0)
-      for i in minColIndex hom .. maxColIndex hom for b in rec.basis repeat
-        hom(r, i) := b
-      n:N := 1                 -- number of equations already solved
-      while r > mr repeat
-        r := r - 1
-        c := c - 1
-        firstnonzero(m, r) ^= c => error "backsolve: undetermined system"
-        degree(eq := m(r, c)) > 0 => error "backsolve: pivot of order > 0"
-        a := leadingCoefficient(eq)::F
-        if part? then
-           part(r + offset) := (v(r + offset) - applyLodo(m, r, part, n)) / a
-        for i in minColIndex hom .. maxColIndex hom repeat
-          hom(r, i) := - applyLodo0(m, r, hom, i, n)
-        n := n + 1
-      bas:List(V) := [column(hom,i) for i in minColIndex hom..maxColIndex hom]
-      part? => [part, bas]
-      ["failed", bas]
-
-    solveInField(m, v, solve) ==
-      ((n := nrows m) = ncols m) and
-         ((u := M2F(diagonalMatrix [diff for i in 1..n] - m)) case MF) =>
-             (uu := solve(u::MF, v, FSL2USL solve(#1, #2))) case "failed" =>
-                  ["failed", empty()]
-             rc := uu::Record(particular:V, basis:MF)
-             [rc.particular, [column(rc.basis, i) for i in 1..ncols(rc.basis)]]
-      rec := triangulate(m, v)
-      backsolve(rec.mat, rec.vec, solve)
-
-    M2F m ==
-        mf:MF := new(nrows m, ncols m, 0)
-        for i in minRowIndex m .. maxRowIndex m repeat
-            for j in minColIndex m .. maxColIndex m repeat
-                (u := retractIfCan(m(i, j))@Union(F, "failed")) case "failed" =>
-                     return "failed"
-                mf(i, j) := u::F
-        mf
-
-    FSL2USL rec ==
-        rec.particular case "failed" => "failed"
-        [rec.particular::F, rec.basis]
-
--- returns the index of the first nonzero entry in row r of m
-    firstnonzero(m, r) ==
-      for c in minColIndex m .. maxColIndex m repeat
-        m(r, c) ^= 0 => return c
-      error "firstnonzero: zero row"
-
--- computes +/[m(r, i) v(i) for i ranging over the last n columns of m]
-    applyLodo(m, r, v, n) ==
-      ans:F := 0
-      c := maxColIndex m
-      cv := maxIndex v
-      for i in 1..n repeat
-        ans := ans + m(r, c) (v cv)
-        c := c - 1
-        cv := cv - 1
-      ans
-
--- computes +/[m(r, i) mm(i, c) for i ranging over the last n columns of m]
-    applyLodo0(m, r, mm, c, n) ==
-      ans := 0
-      rr := maxRowIndex mm
-      cc := maxColIndex m
-      for i in 1..n repeat
-        ans := ans + m(r, cc) mm(rr, c)
-        cc := cc - 1
-        rr := rr - 1
-      ans
-
-    triangulate(m:M, v:V) ==
-      x := copy m
-      w := copy v
-      nrows := maxRowIndex x
-      ncols := maxColIndex x
-      minr  := i := minRowIndex x
-      offset := minIndex w - minr
-      for j in minColIndex x .. ncols repeat
-        if i > nrows then leave x
-        rown := minr - 1
-        for k in i .. nrows repeat
-          if (x(k, j) ^= 0) and ((rown = minr - 1) or
-                              degree x(k,j) < degree x(rown,j)) then rown := k
-          rown = minr - 1 => "enuf"
-          x := swapRows_!(x, i, rown)
-          swap_!(w, i + offset, rown + offset)
-        for k in i+1 .. nrows | x(k, j) ^= 0 repeat
-          l := rightLcm(x(i,j), x(k,j))
-          a := rightQuotient(l, x(i, j))
-          b := rightQuotient(l, x(k, j))
-          -- l = a x(i,j) = b x(k,j)
-          for k1 in j+1 .. ncols repeat
-            x(k, k1) :=  a * x(i, k1) - b * x(k, k1)
-          x(k, j) := 0
-          w(k + offset) := a(w(i + offset)) - b(w(k + offset))
-        i := i+1
-      [x, w]
-
-@
-\section{package ODERED ReduceLODE}
-<<package ODERED ReduceLODE>>=
-)abbrev package ODERED ReduceLODE
-++ Author: Manuel Bronstein
-++ Date Created: 19 August 1991
-++ Date Last Updated: 11 April 1994
-++ Description: Elimination of an algebraic from the coefficentss
-++ of a linear ordinary differential equation.
-ReduceLODE(F, L, UP, A, LO): Exports == Implementation where
-  F : Field
-  L : LinearOrdinaryDifferentialOperatorCategory F
-  UP: UnivariatePolynomialCategory F
-  A : MonogenicAlgebra(F, UP)
-  LO: LinearOrdinaryDifferentialOperatorCategory A
-
-  V ==> Vector F
-  M ==> Matrix L
-
-  Exports ==> with
-    reduceLODE: (LO, A) -> Record(mat:M, vec:V)
-      ++ reduceLODE(op, g) returns \spad{[m, v]} such that
-      ++ any solution in \spad{A} of \spad{op z = g}
-      ++ is of the form \spad{z = (z_1,...,z_m) . (b_1,...,b_m)} where
-      ++ the \spad{b_i's} are the basis of \spad{A} over \spad{F} returned
-      ++ by \spadfun{basis}() from \spad{A}, and the \spad{z_i's} satisfy the
-      ++ differential system \spad{M.z = v}.
-
-  Implementation ==> add
-    matF2L: Matrix F -> M
-
-    diff := D()$L
-
--- coerces a matrix of elements of F into a matrix of (order 0) L.O.D.O's
-    matF2L m ==
-      map(#1::L, m)$MatrixCategoryFunctions2(F, V, V, Matrix F,
-                                                L, Vector L, Vector L, M)
-
--- This follows the algorithm and notation of
---  "The Risch Differential Equation on an Algebraic Curve", M. Bronstein,
--- in 'Proceedings of ISSAC '91', Bonn, BRD, ACM Press, pp.241-246, July 1991.
-    reduceLODE(l, g) ==
-      n := rank()$A
--- md is the basic differential matrix (D x I + Dy)
-      md := matF2L transpose derivationCoordinates(basis(), diff #1)
-      for i in minRowIndex md .. maxRowIndex md
-        for j in minColIndex md .. maxColIndex md repeat
-          md(i, j) := diff + md(i, j)
--- mdi will go through the successive powers of md
-      mdi := copy md
-      sys := matF2L(transpose regularRepresentation coefficient(l, 0))
-      for i in 1..degree l repeat
-        sys := sys +
-                matF2L(transpose regularRepresentation coefficient(l, i)) * mdi
-        mdi := md * mdi
-      [sys, coordinates g]
-
-@
-\section{package ODEPAL PureAlgebraicLODE}
-<<package ODEPAL PureAlgebraicLODE>>=
-)abbrev package ODEPAL PureAlgebraicLODE
-++ Author: Manuel Bronstein
-++ Date Created: 21 August 1991
-++ Date Last Updated: 3 February 1994
-++ Description: In-field solution of an linear ordinary differential equation,
-++ pure algebraic case.
-PureAlgebraicLODE(F, UP, UPUP, R): Exports == Implementation where
-  F   : Join(Field, CharacteristicZero,
-             RetractableTo Integer, RetractableTo Fraction Integer)
-  UP  : UnivariatePolynomialCategory F
-  UPUP: UnivariatePolynomialCategory Fraction UP
-  R   : FunctionFieldCategory(F, UP, UPUP)
-
-  RF  ==> Fraction UP
-  V   ==> Vector RF
-  U   ==> Union(R, "failed")
-  REC ==> Record(particular: Union(RF, "failed"), basis: List RF)
-  L   ==> LinearOrdinaryDifferentialOperator1 R
-  LQ  ==> LinearOrdinaryDifferentialOperator1 RF
-
-  Exports ==> with
-    algDsolve: (L, R) -> Record(particular: U, basis: List R)
-      ++ algDsolve(op, g) returns \spad{["failed", []]} if the equation
-      ++ \spad{op y = g} has no solution in \spad{R}. Otherwise, it returns
-      ++ \spad{[f, [y1,...,ym]]} where \spad{f} is a particular rational
-      ++ solution and the \spad{y_i's} form a basis for the solutions in
-      ++ \spad{R} of the homogeneous equation.
-
-  Implementation ==> add
-    import RationalLODE(F, UP)
-    import SystemODESolver(RF, LQ)
-    import ReduceLODE(RF, LQ, UPUP, R, L)
-
-    algDsolve(l, g) ==
-      rec := reduceLODE(l, g)
-      sol := solveInField(rec.mat, rec.vec, ratDsolve)
-      bas:List(R) := [represents v for v in sol.basis]
-      (u := sol.particular) case V => [represents(u::V), bas]
-      ["failed", bas]
-
-@
-\section{License}
-<<license>>=
---Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
---All rights reserved.
---
---Redistribution and use in source and binary forms, with or without
---modification, are permitted provided that the following conditions are
---met:
---
---    - Redistributions of source code must retain the above copyright
---      notice, this list of conditions and the following disclaimer.
---
---    - Redistributions in binary form must reproduce the above copyright
---      notice, this list of conditions and the following disclaimer in
---      the documentation and/or other materials provided with the
---      distribution.
---
---    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
---      names of its contributors may be used to endorse or promote products
---      derived from this software without specific prior written permission.
---
---THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
---IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
---TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
---PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
---OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
---EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
---PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
---PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
---LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
---NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
---SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-@
-<<*>>=
-<<license>>
-
--- Compile order for the differential equation solver:
--- oderf.spad  odealg.spad  nlode.spad  nlinsol.spad  riccati.spad  odeef.spad
-
-<<package ODESYS SystemODESolver>>
-<<package ODERED ReduceLODE>>
-<<package ODEPAL PureAlgebraicLODE>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/odeef.spad.pamphlet b/src/algebra/odeef.spad.pamphlet
deleted file mode 100644
index 734344a..0000000
--- a/src/algebra/odeef.spad.pamphlet
+++ /dev/null
@@ -1,643 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra odeef.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package REDORDER ReductionOfOrder}
-<<package REDORDER ReductionOfOrder>>=
-)abbrev package REDORDER ReductionOfOrder
-++ Author: Manuel Bronstein
-++ Date Created: 4 November 1991
-++ Date Last Updated: 3 February 1994
-++ Description:
-++ \spadtype{ReductionOfOrder} provides
-++ functions for reducing the order of linear ordinary differential equations
-++ once some solutions are known.
-++ Keywords: differential equation, ODE
-ReductionOfOrder(F, L): Exports == Impl where
-  F: Field
-  L: LinearOrdinaryDifferentialOperatorCategory F
-
-  Z ==> Integer
-  A ==> PrimitiveArray F
-
-  Exports ==> with
-    ReduceOrder: (L, F) -> L
-      ++ ReduceOrder(op, s) returns \spad{op1} such that for any solution
-      ++ \spad{z} of \spad{op1 z = 0}, \spad{y = s \int z} is a solution of
-      ++ \spad{op y = 0}. \spad{s} must satisfy \spad{op s = 0}.
-    ReduceOrder: (L, List F) -> Record(eq:L, op:List F)
-      ++ ReduceOrder(op, [f1,...,fk]) returns \spad{[op1,[g1,...,gk]]} such that
-      ++ for any solution \spad{z} of \spad{op1 z = 0},
-      ++ \spad{y = gk \int(g_{k-1} \int(... \int(g1 \int z)...)} is a solution
-      ++ of \spad{op y = 0}. Each \spad{fi} must satisfy \spad{op fi = 0}.
-
-  Impl ==> add
-    ithcoef   : (L, Z, A) -> F
-    locals    : (A, Z, Z) -> F
-    localbinom: (Z, Z) -> Z
-
-    diff := D()$L
-
-    localbinom(j, i) == (j > i => binomial(j, i+1); 0)
-    locals(s, j, i)  == (j > i => qelt(s, j - i - 1); 0)
-
-    ReduceOrder(l:L, sols:List F) ==
-      empty? sols => [l, empty()]
-      neweq := ReduceOrder(l, sol := first sols)
-      rec := ReduceOrder(neweq, [diff(s / sol) for s in rest sols])
-      [rec.eq, concat_!(rec.op, sol)]
-
-    ithcoef(eq, i, s) ==
-      ans:F := 0
-      while eq ^= 0 repeat
-          j   := degree eq
-          ans := ans + localbinom(j, i) * locals(s,j,i) * leadingCoefficient eq
-          eq  := reductum eq
-      ans
-
-    ReduceOrder(eq:L, sol:F) ==
-      s:A := new(n := degree eq, 0)         -- will contain derivatives of sol
-      si := sol                             -- will run through the derivatives
-      qsetelt_!(s, 0, si)
-      for i in 1..(n-1)::NonNegativeInteger repeat 
-          qsetelt_!(s, i, si := diff si)
-      ans:L := 0
-      for i in 0..(n-1)::NonNegativeInteger repeat
-          ans := ans + monomial(ithcoef(eq, i, s), i)
-      ans
-
-@
-\section{package LODEEF ElementaryFunctionLODESolver}
-<<package LODEEF ElementaryFunctionLODESolver>>=
-)abbrev package LODEEF ElementaryFunctionLODESolver
-++ Author: Manuel Bronstein
-++ Date Created: 3 February 1994
-++ Date Last Updated: 9 March 1994
-++ Description:
-++ \spad{ElementaryFunctionLODESolver} provides the top-level
-++ functions for finding closed form solutions of linear ordinary
-++ differential equations and initial value problems.
-++ Keywords: differential equation, ODE
-ElementaryFunctionLODESolver(R, F, L): Exports == Implementation where
-  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
-          LinearlyExplicitRingOver Integer, CharacteristicZero)
-  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
-          PrimitiveFunctionCategory)
-  L: LinearOrdinaryDifferentialOperatorCategory F
-
-  SY  ==> Symbol
-  N   ==> NonNegativeInteger
-  K   ==> Kernel F
-  V   ==> Vector F
-  M   ==> Matrix F
-  UP  ==> SparseUnivariatePolynomial F
-  RF  ==> Fraction UP
-  UPUP==> SparseUnivariatePolynomial RF
-  P   ==> SparseMultivariatePolynomial(R, K)
-  P2  ==> SparseMultivariatePolynomial(P, K)
-  LQ  ==> LinearOrdinaryDifferentialOperator1 RF
-  REC ==> Record(particular: F, basis: List F)
-  U   ==> Union(REC, "failed")
-  ALGOP  ==> "%alg"
-
-  Exports ==> with
-    solve: (L, F, SY) -> U
-      ++ solve(op, g, x) returns either a solution of the ordinary differential
-      ++ equation \spad{op y = g} or "failed" if no non-trivial solution can be
-      ++ found; When found, the solution is returned in the form
-      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
-      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
-      ++ associated homogenuous equation \spad{op y = 0}.
-      ++ A full basis for the solutions of the homogenuous equation
-      ++ is not always returned, only the solutions which were found;
-      ++ \spad{x} is the dependent variable.
-    solve: (L, F, SY, F, List F) -> Union(F, "failed")
-      ++ solve(op, g, x, a, [y0,...,ym]) returns either the solution
-      ++ of the initial value problem \spad{op y = g, y(a) = y0, y'(a) = y1,...}
-      ++ or "failed" if the solution cannot be found;
-      ++ \spad{x} is the dependent variable.
-
-  Implementation ==> add
-    import Kovacic(F, UP)
-    import ODETools(F, L)
-    import RationalLODE(F, UP)
-    import RationalRicDE(F, UP)
-    import ODEIntegration(R, F)
-    import ConstantLODE(R, F, L)
-    import IntegrationTools(R, F)
-    import ReductionOfOrder(F, L)
-    import ReductionOfOrder(RF, LQ)
-    import PureAlgebraicIntegration(R, F, L)
-    import FunctionSpacePrimitiveElement(R, F)
-    import LinearSystemMatrixPackage(F, V, V, M)
-    import SparseUnivariatePolynomialFunctions2(RF, F)
-    import FunctionSpaceUnivariatePolynomialFactor(R, F, UP)
-    import LinearOrdinaryDifferentialOperatorFactorizer(F, UP)
-    import PolynomialCategoryQuotientFunctions(IndexedExponents K,
-                                                             K, R, P, F)
-
-    upmp       : (P, List K) -> P2
-    downmp     : (P2, List K, List P) -> P
-    xpart      : (F, SY) -> F
-    smpxpart   : (P, SY, List K, List P) -> P
-    multint    : (F, List F, SY) -> F
-    ulodo      : (L, K) -> LQ
-    firstOrder : (F, F, F, SY) -> REC
-    rfSolve    : (L, F, K, SY) -> U
-    ratlogsol  : (LQ, List RF, K, SY) -> List F
-    expsols    : (LQ, K, SY) -> List F
-    homosolve  : (L, LQ, List RF, K, SY) -> List F
-    homosolve1 : (L, List F, K, SY) -> List F
-    norf1      : (L, K, SY, N) -> List F
-    kovode     : (LQ, K, SY) -> List F
-    doVarParams: (L, F, List F, SY) -> U
-    localmap   : (F -> F, L) -> L
-    algSolve   : (L, F, K, List K, SY) -> U
-    palgSolve  : (L, F, K, K, SY) -> U
-    lastChance : (L, F, SY) -> U
-
-    diff := D()$L
-
-    smpxpart(p, x, l, lp) == downmp(primitivePart upmp(p, l), l, lp)
-    downmp(p, l, lp)      == ground eval(p, l, lp)
-    homosolve(lf, op, sols, k, x) == homosolve1(lf, ratlogsol(op,sols,k,x),k,x)
-
--- left hand side has algebraic (not necessarily pure) coefficients
-    algSolve(op, g, k, l, x) ==
-      symbolIfCan(kx := ksec(k, l, x)) case SY => palgSolve(op, g, kx, k, x)
-      has?(operator kx, ALGOP) =>
-        rec := primitiveElement(kx::F, k::F)
-        z   := rootOf(rec.prim)
-        lk:List K := [kx, k]
-        lv:List F := [(rec.pol1) z, (rec.pol2) z]
-        (u := solve(localmap(eval(#1, lk, lv), op), eval(g, lk, lv), x))
-            case "failed" => "failed"
-        rc := u::REC
-        kz := retract(z)@K
-        [eval(rc.particular, kz, rec.primelt),
-            [eval(f, kz, rec.primelt) for f in rc.basis]]
-      lastChance(op, g, x)
-
-    doVarParams(eq, g, bas, x) ==
-      (u := particularSolution(eq, g, bas, int(#1, x))) case "failed" =>
-         lastChance(eq, g, x)
-      [u::F, bas]
-
-    lastChance(op, g, x) ==
---      one? degree op => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
-      (degree op) = 1 => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
-      "failed"
-
--- solves a0 y + a1 y' = g
--- does not check whether there is a solution in the field generated by
--- a0, a1 and g
-    firstOrder(a0, a1, g, x) ==
-      h := xpart(expint(- a0 / a1, x), x)
-      [h * int((g / h) / a1, x), [h]]
-
--- xpart(f,x) removes any constant not involving x from f
-    xpart(f, x) ==
-      l  := reverse_! varselect(tower f, x)
-      lp := [k::P for k in l]
-      smpxpart(numer f, x, l, lp) / smpxpart(denom f, x, l, lp)
-
-    upmp(p, l) ==
-      empty? l => p::P2
-      up := univariate(p, k := first l)
-      l := rest l
-      ans:P2 := 0
-      while up ^= 0 repeat
-        ans := ans + monomial(upmp(leadingCoefficient up, l), k, degree up)
-        up  := reductum up
-      ans
-
--- multint(a, [g1,...,gk], x) returns gk \int(g(k-1) \int(....g1 \int(a))...)
-    multint(a, l, x) ==
-       for g in l repeat a := g * xpart(int(a, x), x)
-       a
-
-    expsols(op, k, x) ==
---      one? degree op =>
-      (degree op) = 1 =>
-          firstOrder(multivariate(coefficient(op, 0), k),
-                     multivariate(leadingCoefficient op, k), 0, x).basis
-      [xpart(expint(multivariate(h, k), x), x) for h in ricDsolve(op, ffactor)]
-
--- Finds solutions with rational logarithmic derivative
-    ratlogsol(oper, sols, k, x) ==
-      bas := [xpart(multivariate(h, k), x) for h in sols]
-      degree(oper) = #bas => bas            -- all solutions are found already
-      rec := ReduceOrder(oper, sols)
-      le := expsols(rec.eq, k, x)
-      int:List(F) := [xpart(multivariate(h, k), x) for h in rec.op]
-      concat_!([xpart(multivariate(h, k), x) for h in sols],
-               [multint(e, int, x) for e in le])
-
-    homosolve1(oper, sols, k, x) ==
-      zero?(n := (degree(oper) - #sols)::N) => sols   -- all solutions found
-      rec := ReduceOrder(oper, sols)
-      int:List(F) := [xpart(h, x) for h in rec.op]
-      concat_!(sols, [multint(e, int, x) for e in norf1(rec.eq, k, x, n::N)])
-
--- if the coefficients are rational functions, then the equation does not
--- not have a proper 1st-order right factor over the rational functions
-    norf1(op, k, x, n) ==
---      one? n => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
-      (n = 1) => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
--- for order > 2, we check that the coeffs are still rational functions
-      symbolIfCan(kmax vark(coefficients op, x)) case SY =>
-        eq := ulodo(op, k)
-        n = 2 => kovode(eq, k, x)
-        eq := last factor1 eq        -- eq cannot have order 1
-        degree(eq) = 2 =>
-          empty?(bas := kovode(eq, k, x)) => empty()
-          homosolve1(op, bas, k, x)
-        empty()
-      empty()
-
-    kovode(op, k, x) ==
-      b := coefficient(op, 1)
-      a := coefficient(op, 2)
-      (u := kovacic(coefficient(op, 0), b, a, ffactor)) case "failed" => empty()
-      p := map(multivariate(#1, k), u::UPUP)
-      ba := multivariate(- b / a, k)
--- if p has degree 2 (case 2), then it must be squarefree since the
--- ode is irreducible over the rational functions, so the 2 roots of p
--- are distinct and must yield 2 independent solutions.
-      degree(p) = 2 => [xpart(expint(ba/(2::F) + e, x), x) for e in zerosOf p]
--- otherwise take 1 root of p and find the 2nd solution by reduction of order
-      y1 := xpart(expint(ba / (2::F) + zeroOf p, x), x)
-      [y1, y1 * xpart(int(expint(ba, x) / y1**2, x), x)]
-
-    solve(op:L, g:F, x:SY) ==
-      empty?(l := vark(coefficients op, x)) => constDsolve(op, g, x)
-      symbolIfCan(k := kmax l) case SY => rfSolve(op, g, k, x)
-      has?(operator k, ALGOP) => algSolve(op, g, k, l, x)
-      lastChance(op, g, x)
-
-    ulodo(eq, k) ==
-        op:LQ := 0
-        while eq ^= 0 repeat
-            op := op + monomial(univariate(leadingCoefficient eq, k), degree eq)
-            eq := reductum eq
-        op
-
--- left hand side has rational coefficients
-    rfSolve(eq, g, k, x) ==
-      op := ulodo(eq, k)
-      empty? remove_!(k, varselect(kernels g, x)) =>  -- i.e. rhs is rational
-        rc := ratDsolve(op, univariate(g, k))
-        rc.particular case "failed" =>                -- this implies g ^= 0
-          doVarParams(eq, g, homosolve(eq, op, rc.basis, k, x), x)
-        [multivariate(rc.particular::RF, k), homosolve(eq, op, rc.basis, k, x)]
-      doVarParams(eq, g, homosolve(eq, op, ratDsolve(op, 0).basis, k, x), x)
-
-    solve(op, g, x, a, y0) ==
-      (u := solve(op, g, x)) case "failed" => "failed"
-      hp := h := (u::REC).particular
-      b := (u::REC).basis
-      v:V := new(n := #y0, 0)
-      kx:K := kernel x
-      for i in minIndex v .. maxIndex v for yy in y0 repeat
-        v.i := yy - eval(h, kx, a)
-        h := diff h
-      (sol := particularSolution(map_!(eval(#1,kx,a),wronskianMatrix(b,n)), v))
-         case "failed" => "failed"
-      for f in b for i in minIndex(s := sol::V) .. repeat
-        hp := hp + s.i * f
-      hp
-
-    localmap(f, op) ==
-        ans:L := 0
-        while op ^= 0 repeat
-            ans := ans + monomial(f leadingCoefficient op, degree op)
-            op  := reductum op
-        ans
-
--- left hand side has pure algebraic coefficients
-    palgSolve(op, g, kx, k, x) ==
-      rec := palgLODE(op, g, kx, k, x)   -- finds solutions in the coef. field
-      rec.particular case "failed" =>
-        doVarParams(op, g, homosolve1(op, rec.basis, k, x), x)
-      [(rec.particular)::F, homosolve1(op, rec.basis, k, x)]
-
-@
-\section{package ODEEF ElementaryFunctionODESolver}
-<<package ODEEF ElementaryFunctionODESolver>>=
-)abbrev package ODEEF ElementaryFunctionODESolver
-++ Author: Manuel Bronstein
-++ Date Created: 18 March 1991
-++ Date Last Updated: 8 March 1994
-++ Description:
-++ \spad{ElementaryFunctionODESolver} provides the top-level
-++ functions for finding closed form solutions of ordinary
-++ differential equations and initial value problems.
-++ Keywords: differential equation, ODE
-ElementaryFunctionODESolver(R, F): Exports == Implementation where
-  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
-          LinearlyExplicitRingOver Integer, CharacteristicZero)
-  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
-          PrimitiveFunctionCategory)
-
-  N   ==> NonNegativeInteger
-  OP  ==> BasicOperator
-  SY  ==> Symbol
-  K   ==> Kernel F
-  EQ  ==> Equation F
-  V   ==> Vector F
-  M   ==> Matrix F
-  UP  ==> SparseUnivariatePolynomial F
-  P   ==> SparseMultivariatePolynomial(R, K)
-  LEQ ==> Record(left:UP, right:F)
-  NLQ ==> Record(dx:F, dy:F)
-  REC ==> Record(particular: F, basis: List F)
-  VEC ==> Record(particular: V, basis: List V)
-  ROW ==> Record(index: Integer, row: V, rh: F)
-  SYS ==> Record(mat:M, vec: V)
-  U   ==> Union(REC, F, "failed")
-  UU  ==> Union(F, "failed")
-  OPDIFF ==> "%diff"::SY
-
-  Exports ==> with
-    solve: (M, V, SY) -> Union(VEC, "failed")
-      ++ solve(m, v, x) returns \spad{[v_p, [v_1,...,v_m]]} such that
-      ++ the solutions of the system \spad{D y = m y + v} are
-      ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
-      ++ constants, and the \spad{v_i's} form a basis for the solutions of
-      ++ \spad{D y = m y}.
-      ++ \spad{x} is the dependent variable.
-    solve: (M, SY) -> Union(List V, "failed")
-      ++ solve(m, x) returns a basis for the solutions of \spad{D y = m y}.
-      ++ \spad{x} is the dependent variable.
-    solve: (List EQ, List OP, SY) -> Union(VEC, "failed")
-      ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
-      ++ or, if the equations form a fist order linear system, a solution
-      ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
-      ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
-      ++ solutions of the associated homogenuous system.
-      ++ error if the equations do not form a first order linear system
-    solve: (List F, List OP, SY) -> Union(VEC, "failed")
-      ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
-      ++ or, if the equations form a fist order linear system, a solution
-      ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
-      ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
-      ++ solutions of the associated homogenuous system.
-      ++ error if the equations do not form a first order linear system
-    solve: (EQ, OP, SY) -> U
-      ++ solve(eq, y, x) returns either a solution of the ordinary differential
-      ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
-      ++ If the equation is linear ordinary, a solution is of the form
-      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution
-      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
-      ++ associated homogenuous equation \spad{f(x,y) = 0};
-      ++ A full basis for the solutions of the homogenuous equation
-      ++ is not always returned, only the solutions which were found;
-      ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
-      ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
-      ++ of the equation for any constant \spad{c};
-      ++ error if the equation is not one of those 2 forms;
-    solve: (F, OP, SY) -> U
-      ++ solve(eq, y, x) returns either a solution of the ordinary differential
-      ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
-      ++ If the equation is linear ordinary, a solution is of the form
-      ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
-      ++ and \spad{[b1,...bm]} are linearly independent solutions of the
-      ++ associated homogenuous equation \spad{f(x,y) = 0};
-      ++ A full basis for the solutions of the homogenuous equation
-      ++ is not always returned, only the solutions which were found;
-      ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
-      ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
-      ++ of the equation for any constant \spad{c};
-    solve: (EQ, OP, EQ, List F) -> UU
-      ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
-      ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
-      ++ or "failed" if the solution cannot be found;
-      ++ error if the equation is not one linear ordinary or of the form
-      ++ \spad{dy/dx = f(x,y)};
-    solve: (F, OP, EQ, List F) -> UU
-      ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
-      ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
-      ++ or "failed" if the solution cannot be found;
-      ++ error if the equation is not one linear ordinary or of the form
-      ++ \spad{dy/dx = f(x,y)};
-
-  Implementation ==> add
-    import ODEIntegration(R, F)
-    import IntegrationTools(R, F)
-    import NonLinearFirstOrderODESolver(R, F)
-
-    getfreelincoeff : (F, K, SY) -> F
-    getfreelincoeff1: (F, K, List F) -> F
-    getlincoeff     : (F, K) -> F
-    getcoeff        : (F, K) -> UU
-    parseODE        : (F, OP, SY) -> Union(LEQ, NLQ)
-    parseLODE       : (F, List K, UP, SY) -> LEQ
-    parseSYS        : (List F, List OP, SY) -> Union(SYS, "failed")
-    parseSYSeq      : (F, List K, List K, List F, SY) -> Union(ROW, "failed")
-
-    solve(diffeq:EQ, y:OP, x:SY) == solve(lhs diffeq - rhs diffeq, y, x)
-
-    solve(leq: List EQ, lop: List OP, x:SY) ==
-        solve([lhs eq - rhs eq for eq in leq], lop, x)
-
-    solve(diffeq:EQ, y:OP, center:EQ, y0:List F) ==
-      solve(lhs diffeq - rhs diffeq, y, center, y0)
-
-    solve(m:M, x:SY) ==
-        (u := solve(m, new(nrows m, 0), x)) case "failed" => "failed"
-        u.basis
-
-    solve(m:M, v:V, x:SY) ==
-        Lx := LinearOrdinaryDifferentialOperator(F, diff x)
-        uu := solve(m, v, solve(#1, #2,
-               x)$ElementaryFunctionLODESolver(R, F, Lx))$SystemODESolver(F, Lx)
-        uu case "failed" => "failed"
-        rec := uu::Record(particular: V, basis: M)
-        [rec.particular, [column(rec.basis, i) for i in 1..ncols(rec.basis)]]
-
-    solve(diffeq:F, y:OP, center:EQ, y0:List F) ==
-      a := rhs center
-      kx:K := kernel(x := retract(lhs(center))@SY)
-      (ur := parseODE(diffeq, y, x)) case NLQ =>
---        not one?(#y0) => error "solve: more than one initial condition!"
-        not ((#y0) = 1) => error "solve: more than one initial condition!"
-        rc := ur::NLQ
-        (u := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
-        u::F - eval(u::F,  [kx, retract(y(x::F))@K], [a, first y0])
-      rec := ur::LEQ
-      p := rec.left
-      Lx := LinearOrdinaryDifferentialOperator(F, diff x)
-      op:Lx := 0
-      while p ^= 0 repeat
-        op := op + monomial(leadingCoefficient p, degree p)
-        p  := reductum p
-      solve(op, rec.right, x, a, y0)$ElementaryFunctionLODESolver(R, F, Lx)
-
-    solve(leq: List F, lop: List OP, x:SY) ==
-        (u := parseSYS(leq, lop, x)) case SYS =>
-            rec := u::SYS
-            solve(rec.mat, rec.vec, x)
-        error "solve: not a first order linear system"
-
-    solve(diffeq:F, y:OP, x:SY) ==
-      (u := parseODE(diffeq, y, x)) case NLQ =>
-        rc := u::NLQ
-        (uu := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
-        uu::F
-      rec := u::LEQ
-      p := rec.left
-      Lx := LinearOrdinaryDifferentialOperator(F, diff x)
-      op:Lx := 0
-      while p ^= 0 repeat
-        op := op + monomial(leadingCoefficient p, degree p)
-        p  := reductum p
-      (uuu := solve(op, rec.right, x)$ElementaryFunctionLODESolver(R, F, Lx))
-         case "failed" => "failed"
-      uuu::REC
-
--- returns [M, v] s.t. the equations are D x = M x + v
-    parseSYS(eqs, ly, x) ==
-      (n := #eqs) ^= #ly => "failed"
-      m:M := new(n, n, 0)
-      v:V := new(n, 0)
-      xx := x::F
-      lf := [y xx for y in ly]
-      lk0:List(K) := [retract(f)@K for f in lf]
-      lk1:List(K) := [retract(differentiate(f, x))@K for f in lf]
-      for eq in eqs repeat
-          (u := parseSYSeq(eq,lk0,lk1,lf,x)) case "failed" => return "failed"
-          rec := u::ROW
-          setRow_!(m, rec.index, rec.row)
-          v(rec.index) := rec.rh
-      [m, v]
-
-    parseSYSeq(eq, l0, l1, lf, x) ==
-      l := [k for k in varselect(kernels eq, x) | is?(k, OPDIFF)]
-      empty? l or not empty? rest l or zero?(n := position(k := first l,l1)) =>
-         "failed"
-      c := getfreelincoeff1(eq, k, lf)
-      eq := eq - c * k::F
-      v:V := new(#l0, 0)
-      for y in l0 for i in 1.. repeat
-          ci := getfreelincoeff1(eq, y, lf)
-          v.i := - ci / c
-          eq := eq - ci * y::F
-      [n, v, -eq]
-
--- returns either [p, g] where the equation (diffeq) is of the form p(D)(y) = g
--- or [p, q] such that the equation (diffeq) is of the form p dx + q dy = 0
-    parseODE(diffeq, y, x) ==
-      f := y(x::F)
-      l:List(K) := [retract(f)@K]
-      n:N := 2
-      for k in varselect(kernels diffeq, x) | is?(k, OPDIFF) repeat
-        if (m := height k) > n then n := m
-      n := (n - 2)::N
--- build a list of kernels in the order [y^(n)(x),...,y''(x),y'(x),y(x)]
-      for i in 1..n repeat
-        l := concat(retract(f := differentiate(f, x))@K, l)
-      k:K   -- #$^#& compiler requires this line and the next one too...
-      c:F
-      while not(empty? l) and zero?(c := getlincoeff(diffeq, k := first l))
-        repeat l := rest l
-      empty? l or empty? rest l => error "parseODE: equation has order 0"
-      diffeq := diffeq - c * (k::F)
-      ny := name y
-      l := rest l
-      height(k) > 3 => parseLODE(diffeq, l, monomial(c, #l), ny)
-      (u := getcoeff(diffeq, k := first l)) case "failed" => [diffeq, c]
-      eqrhs := (d := u::F) * (k::F) - diffeq
-      freeOf?(eqrhs, ny) and freeOf?(c, ny) and freeOf?(d, ny) =>
-        [monomial(c, 1) + d::UP, eqrhs]
-      [diffeq, c]
-
--- returns [p, g] where the equation (diffeq) is of the form p(D)(y) = g
-    parseLODE(diffeq, l, p, y) ==
-      not freeOf?(leadingCoefficient p, y) =>
-        error "parseLODE: not a linear ordinary differential equation"
-      d := degree(p)::Integer - 1
-      for k in l repeat
-        p := p + monomial(c := getfreelincoeff(diffeq, k, y), d::N)
-        d := d - 1
-        diffeq := diffeq - c * (k::F)
-      freeOf?(diffeq, y) => [p, - diffeq]
-      error "parseLODE: not a linear ordinary differential equation"
-
-    getfreelincoeff(f, k, y) ==
-      freeOf?(c := getlincoeff(f, k), y) => c
-      error "getfreelincoeff: not a linear ordinary differential equation"
-
-    getfreelincoeff1(f, k, ly) ==
-      c := getlincoeff(f, k)
-      for y in ly repeat
-         not freeOf?(c, y) =>
-            error "getfreelincoeff: not a linear ordinary differential equation"
-      c
-
-    getlincoeff(f, k) ==
-      (u := getcoeff(f, k)) case "failed" =>
-        error "getlincoeff: not an appropriate ordinary differential equation"
-      u::F
-
-    getcoeff(f, k) ==
-      (r := retractIfCan(univariate(denom f, k))@Union(P, "failed"))
-        case "failed" or degree(p := univariate(numer f, k)) > 1 => "failed"
-      coefficient(p, 1) / (r::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>>
-
--- Compile order for the differential equation solver:
--- oderf.spad  odealg.spad  nlode.spad  nlinsol.spad  riccati.spad
--- kovacic.spad  lodof.spad  odeef.spad
-
-<<package REDORDER ReductionOfOrder>>
-<<package LODEEF ElementaryFunctionLODESolver>>
-<<package ODEEF ElementaryFunctionODESolver>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/oderf.spad.pamphlet b/src/algebra/oderf.spad.pamphlet
deleted file mode 100644
index 6573a80..0000000
--- a/src/algebra/oderf.spad.pamphlet
+++ /dev/null
@@ -1,900 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra oderf.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package BALFACT BalancedFactorisation}
-<<package BALFACT BalancedFactorisation>>=
-)abbrev package BALFACT BalancedFactorisation
-++ Author: Manuel Bronstein
-++ Date Created: 1 March 1991
-++ Date Last Updated: 11 October 1991
-++ Description: This package provides balanced factorisations of polynomials.
-BalancedFactorisation(R, UP): Exports == Implementation where
-  R  : Join(GcdDomain, CharacteristicZero)
-  UP : UnivariatePolynomialCategory R
-
-  Exports ==> with
-    balancedFactorisation: (UP, UP) -> Factored UP
-      ++ balancedFactorisation(a, b) returns
-      ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
-      ++ \spad{pi} is balanced with respect to b.
-    balancedFactorisation: (UP, List UP) -> Factored UP
-      ++ balancedFactorisation(a, [b1,...,bn]) returns
-      ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
-      ++ pi is balanced with respect to \spad{[b1,...,bm]}.
-
-  Implementation ==> add
-    balSqfr : (UP, Integer, List UP) -> Factored UP
-    balSqfr1: (UP, Integer,      UP) -> Factored UP
-
-    balancedFactorisation(a:UP, b:UP) == balancedFactorisation(a, [b])
-
-    balSqfr1(a, n, b) ==
-      g := gcd(a, b)
-      fa := sqfrFactor((a exquo g)::UP, n)
-      ground? g => fa
-      fa * balSqfr1(g, n, (b exquo (g ** order(b, g)))::UP)
-
-    balSqfr(a, n, l) ==
-      b := first l
-      empty? rest l => balSqfr1(a, n, b)
-      */[balSqfr1(f.factor, n, b) for f in factors balSqfr(a,n,rest l)]
-
-    balancedFactorisation(a:UP, l:List UP) ==
-      empty?(ll := select(#1 ^= 0, l)) =>
-        error "balancedFactorisation: 2nd argument is empty or all 0"
-      sa := squareFree a
-      unit(sa) * */[balSqfr(f.factor,f.exponent,ll) for f in factors sa])
-
-@
-\section{package BOUNDZRO BoundIntegerRoots}
-<<package BOUNDZRO BoundIntegerRoots>>=
-)abbrev package BOUNDZRO BoundIntegerRoots
-++ Author: Manuel Bronstein
-++ Date Created: 11 March 1991
-++ Date Last Updated: 18 November 1991
-++ Description:
-++   \spadtype{BoundIntegerRoots} provides functions to
-++   find lower bounds on the integer roots of a polynomial.
-BoundIntegerRoots(F, UP): Exports == Implementation where
-  F  : Join(Field, RetractableTo Fraction Integer)
-  UP : UnivariatePolynomialCategory F
-
-  Z   ==> Integer
-  Q   ==> Fraction Z
-  K   ==> Kernel F
-  UPQ ==> SparseUnivariatePolynomial Q
-  ALGOP ==> "%alg"
-
-  Exports ==> with
-    integerBound: UP -> Z
-      ++ integerBound(p) returns a lower bound on the negative integer
-      ++ roots of p, and 0 if p has no negative integer roots.
-
-  Implementation ==> add
-    import RationalFactorize(UPQ)
-    import UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
-
-    qbound : (UP, UPQ) -> Z
-    zroot1 : UP -> Z
-    qzroot1: UPQ -> Z
-    negint : Q -> Z
-
--- returns 0 if p has no integer root < 0, its negative integer root otherwise
-    qzroot1 p == negint(- leadingCoefficient(reductum p) / leadingCoefficient p)
-
--- returns 0 if p has no integer root < 0, its negative integer root otherwise
-    zroot1 p ==
-      z := - leadingCoefficient(reductum p) / leadingCoefficient p
-      (r := retractIfCan(z)@Union(Q, "failed")) case Q => negint(r::Q)
-      0
-
--- returns 0 if r is not a negative integer, r otherwise
-    negint r ==
-      ((u := retractIfCan(r)@Union(Z, "failed")) case Z) and (u::Z < 0) => u::Z
-      0
-
-    if F has ExpressionSpace then
-      bringDown: F -> Q
-
--- the random substitution used by bringDown is NOT always a ring-homorphism
--- (because of potential algebraic kernels), but is ALWAYS a Z-linear map.
--- this guarantees that bringing down the coefficients of (x + n) q(x) for an
--- integer n yields a polynomial h(x) which is divisible by x + n
--- the only problem is that evaluating with random numbers can cause a
--- division by 0. We should really be able to trap this error later and
--- reevaluate with a new set of random numbers    MB 11/91
-      bringDown f ==
-        t := tower f
-        retract eval(f, t, [random()$Q :: F for k in t])
-
-      integerBound p ==
---        one? degree p => zroot1 p
-        (degree p) = 1 => zroot1 p
-        q1 := map(bringDown, p)
-        q2 := map(bringDown, p)
-        qbound(p, gcd(q1, q2))
-
-    else
-      integerBound p ==
---        one? degree p => zroot1 p
-        (degree p) = 1 => zroot1 p
-        qbound(p, map(retract(#1)@Q, p))
-
--- we can probably do better here (i.e. without factoring)
-    qbound(p, q) ==
-      bound:Z := 0
-      for rec in factors factor q repeat
---        if one?(degree(rec.factor)) and ((r := qzroot1(rec.factor)) < bound)
-        if ((degree(rec.factor)) = 1) and ((r := qzroot1(rec.factor)) < bound)
-           and zero? p(r::Q::F) then bound := r
-      bound
-
-@
-\section{package ODEPRIM PrimitiveRatDE}
-<<package ODEPRIM PrimitiveRatDE>>=
-)abbrev package ODEPRIM PrimitiveRatDE
-++ Author: Manuel Bronstein
-++ Date Created: 1 March 1991
-++ Date Last Updated: 1 February 1994
-++ Description:
-++  \spad{PrimitiveRatDE} provides functions for in-field solutions of linear
-++   ordinary differential equations, in the transcendental case.
-++   The derivation to use is given by the parameter \spad{L}.
-PrimitiveRatDE(F, UP, L, LQ): Exports == Implementation where
-  F  : Join(Field, CharacteristicZero, RetractableTo Fraction Integer)
-  UP : UnivariatePolynomialCategory F
-  L  : LinearOrdinaryDifferentialOperatorCategory UP
-  LQ : LinearOrdinaryDifferentialOperatorCategory Fraction UP
-
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  RF  ==> Fraction UP
-  UP2 ==> SparseUnivariatePolynomial UP
-  REC ==> Record(center:UP, equation:UP)
-
-  Exports ==> with
-    denomLODE: (L, RF) -> Union(UP, "failed")
-      ++ denomLODE(op, g) returns a polynomial d such that
-      ++ any rational solution of \spad{op y = g}
-      ++ is of the form \spad{p/d} for some polynomial p, and
-      ++ "failed", if the equation has no rational solution.
-    denomLODE: (L, List RF) -> UP
-      ++ denomLODE(op, [g1,...,gm]) returns a polynomial
-      ++ d such that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
-      ++ is of the form \spad{p/d} for some polynomial p.
-    indicialEquations: L -> List REC
-      ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
-      ++ the \spad{d_i}'s are the affine singularities of \spad{op},
-      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
-    indicialEquations: (L, UP) -> List REC
-      ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
-      ++ the \spad{d_i}'s are the affine singularities of \spad{op}
-      ++ above the roots of \spad{p},
-      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
-    indicialEquation: (L, F) -> UP
-      ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
-      ++ at \spad{a}.
-    indicialEquations: LQ -> List REC
-      ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
-      ++ the \spad{d_i}'s are the affine singularities of \spad{op},
-      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
-    indicialEquations: (LQ, UP) -> List REC
-      ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
-      ++ the \spad{d_i}'s are the affine singularities of \spad{op}
-      ++ above the roots of \spad{p},
-      ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
-    indicialEquation: (LQ, F) -> UP
-      ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
-      ++ at \spad{a}.
-    splitDenominator: (LQ, List RF) -> Record(eq:L, rh:List RF)
-      ++ splitDenominator(op, [g1,...,gm]) returns \spad{op0, [h1,...,hm]}
-      ++ such that the equations \spad{op y = c1 g1 + ... + cm gm} and
-      ++ \spad{op0 y = c1 h1 + ... + cm hm} have the same solutions.
-
-  Implementation ==> add
-    import BoundIntegerRoots(F, UP)
-    import BalancedFactorisation(F, UP)
-    import InnerCommonDenominator(UP, RF, List UP, List RF)
-    import UnivariatePolynomialCategoryFunctions2(F, UP, UP, UP2)
-
-    tau          : (UP, UP, UP, N) -> UP
-    NPbound      : (UP, L, UP) -> N
-    hdenom       : (L, UP, UP) -> UP
-    denom0       : (Z, L, UP, UP, UP) -> UP
-    indicialEq   : (UP, List N, List UP) -> UP
-    separateZeros: (UP, UP) -> UP
-    UPfact       : N -> UP
-    UP2UP2       : UP -> UP2
-    indeq        : (UP, L) -> UP
-    NPmulambda   : (UP, L) -> Record(mu:Z, lambda:List N, func:List UP)
-
-    diff := D()$L
-
-    UP2UP2 p                    == map(#1::UP, p)
-    indicialEquations(op:L)     == indicialEquations(op, leadingCoefficient op)
-    indicialEquation(op:L, a:F) == indeq(monomial(1, 1) - a::UP, op)
-
-    splitDenominator(op, lg) ==
-      cd := splitDenominator coefficients op
-      f  := cd.den / gcd(cd.num)
-      l:L := 0
-      while op ^= 0 repeat
-          l  := l + monomial(retract(f * leadingCoefficient op), degree op)
-          op := reductum op
-      [l, [f * g for g in lg]]
-
-    tau(p, pp, q, n) ==
-      ((pp ** n) * ((q exquo (p ** order(q, p)))::UP)) rem p
-
-    indicialEquations(op:LQ) ==
-      indicialEquations(splitDenominator(op, empty()).eq)
-
-    indicialEquations(op:LQ, p:UP) ==
-      indicialEquations(splitDenominator(op, empty()).eq, p)
-
-    indicialEquation(op:LQ, a:F) ==
-      indeq(monomial(1, 1) - a::UP, splitDenominator(op, empty()).eq)
-
--- returns z(z-1)...(z-(n-1))
-    UPfact n ==
-      zero? n => 1
-      z := monomial(1, 1)$UP
-      */[z - i::F::UP for i in 0..(n-1)::N]
-
-    indicialEq(c, lamb, lf) ==
-      cp := diff c
-      cc := UP2UP2 c
-      s:UP2 := 0
-      for i in lamb for f in lf repeat
-        s := s + (UPfact i) * UP2UP2 tau(c, cp, f, i)
-      primitivePart resultant(cc, s)
-
-    NPmulambda(c, l) ==
-      lamb:List(N) := [d := degree l]
-      lf:List(UP) := [a := leadingCoefficient l]
-      mup := d::Z - order(a, c)
-      while (l := reductum l) ^= 0 repeat
-          a := leadingCoefficient l
-          if (m := (d := degree l)::Z - order(a, c)) > mup then
-              mup := m
-              lamb := [d]
-              lf := [a]
-          else if (m = mup) then
-              lamb := concat(d, lamb)
-              lf := concat(a, lf)
-      [mup, lamb, lf]
-
--- e = 0 means homogeneous equation
-    NPbound(c, l, e) ==
-      rec := NPmulambda(c, l)
-      n := max(0, - integerBound indicialEq(c, rec.lambda, rec.func))
-      zero? e => n::N
-      max(n, order(e, c)::Z - rec.mu)::N
-
-    hdenom(l, d, e) ==
-      */[dd.factor ** NPbound(dd.factor, l, e)
-                    for dd in factors balancedFactorisation(d, coefficients l)]
-
-    denom0(n, l, d, e, h) ==
-      hdenom(l, d, e) * */[hh.factor ** max(0, order(e, hh.factor) - n)::N
-                                 for hh in factors balancedFactorisation(h, e)]
-
--- returns a polynomials whose zeros are the zeros of e which are not
--- zeros of d
-    separateZeros(d, e) ==
-      ((g := squareFreePart e) exquo gcd(g, squareFreePart d))::UP
-
-    indeq(c, l) ==
-      rec := NPmulambda(c, l)
-      indicialEq(c, rec.lambda, rec.func)
-
-    indicialEquations(op:L, p:UP) ==
-      [[dd.factor, indeq(dd.factor, op)]
-                   for dd in factors balancedFactorisation(p, coefficients op)]
-
--- cannot return "failed" in the homogeneous case
-    denomLODE(l:L, g:RF) ==
-      d := leadingCoefficient l
-      zero? g => hdenom(l, d, 0)
-      h := separateZeros(d, e := denom g)
-      n := degree l
-      (e exquo (h**(n + 1))) case "failed" => "failed"
-      denom0(n, l, d, e, h)
-
-    denomLODE(l:L, lg:List RF) ==
-      empty? lg => denomLODE(l, 0)::UP
-      d := leadingCoefficient l
-      h := separateZeros(d, e := "lcm"/[denom g for g in lg])
-      denom0(degree l, l, d, e, h)
-
-@
-\section{package UTSODETL UTSodetools}
-<<package UTSODETL UTSodetools>>=
-)abbrev package UTSODETL UTSodetools
-++ Author: Manuel Bronstein
-++ Date Created: 31 January 1994
-++ Date Last Updated: 3 February 1994
-++ Description:
-++  \spad{RUTSodetools} provides tools to interface with the series
-++   ODE solver when presented with linear ODEs.
-UTSodetools(F, UP, L, UTS): Exports == Implementation where
-  F  : Ring
-  UP : UnivariatePolynomialCategory F
-  L  : LinearOrdinaryDifferentialOperatorCategory UP
-  UTS: UnivariateTaylorSeriesCategory F
-
-  Exports ==> with
-      UP2UTS:   UP -> UTS
-          ++ UP2UTS(p) converts \spad{p} to a Taylor series.
-      UTS2UP:   (UTS, NonNegativeInteger) -> UP
-          ++ UTS2UP(s, n) converts the first \spad{n} terms of \spad{s}
-          ++ to a univariate polynomial.
-      LODO2FUN: L -> (List UTS -> UTS)
-          ++ LODO2FUN(op) returns the function to pass to the series ODE
-          ++ solver in order to solve \spad{op y = 0}.
-      if F has IntegralDomain then
-          RF2UTS: Fraction UP -> UTS
-              ++ RF2UTS(f) converts \spad{f} to a Taylor series.
-
-  Implementation ==> add
-      fun: (Vector UTS, List UTS) -> UTS
-
-      UP2UTS p ==
-        q := p(monomial(1, 1) + center(0)::UP)
-        +/[monomial(coefficient(q, i), i)$UTS for i in 0..degree q]
-
-      UTS2UP(s, n) ==
-        xmc     := monomial(1, 1)$UP - center(0)::UP
-        xmcn:UP := 1
-        ans:UP  := 0
-        for i in 0..n repeat
-            ans  := ans + coefficient(s, i) * xmcn
-            xmcn := xmc * xmcn
-        ans
-
-      LODO2FUN op ==
-          a := recip(UP2UTS(- leadingCoefficient op))::UTS
-          n := (degree(op) - 1)::NonNegativeInteger
-          v := [a * UP2UTS coefficient(op, i) for i in 0..n]$Vector(UTS)
-          fun(v, #1)
-
-      fun(v, l) ==
-          ans:UTS := 0
-          for b in l for i in 1.. repeat ans := ans + v.i * b
-          ans
-
-      if F has IntegralDomain then
-          RF2UTS f == UP2UTS(numer f) * recip(UP2UTS denom f)::UTS
-
-@
-\section{package ODERAT RationalLODE}
-<<package ODERAT RationalLODE>>=
-)abbrev package ODERAT RationalLODE
-++ Author: Manuel Bronstein
-++ Date Created: 13 March 1991
-++ Date Last Updated: 13 April 1994
-++ Description:
-++  \spad{RationalLODE} provides functions for in-field solutions of linear
-++   ordinary differential equations, in the rational case.
-RationalLODE(F, UP): Exports == Implementation where
-  F  : Join(Field, CharacteristicZero, RetractableTo Integer,
-                                       RetractableTo Fraction Integer)
-  UP : UnivariatePolynomialCategory F
-
-  N   ==> NonNegativeInteger
-  Z   ==> Integer
-  RF  ==> Fraction UP
-  U   ==> Union(RF, "failed")
-  V   ==> Vector F
-  M   ==> Matrix F
-  LODO ==> LinearOrdinaryDifferentialOperator1 RF
-  LODO2==> LinearOrdinaryDifferentialOperator2(UP, RF)
-
-  Exports ==> with
-    ratDsolve: (LODO, RF) -> Record(particular: U, basis: List RF)
-      ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
-      ++ \spad{op y = g} has no rational solution. Otherwise, it returns
-      ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
-      ++ and the yi's form a basis for the rational solutions of the
-      ++ homogeneous equation.
-    ratDsolve: (LODO, List RF) -> Record(basis:List RF, mat:Matrix F)
-      ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
-      ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
-      ++ is of the form \spad{d1 h1 + ... + dq hq} where
-      ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
-    ratDsolve: (LODO2, RF) -> Record(particular: U, basis: List RF)
-      ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
-      ++ \spad{op y = g} has no rational solution. Otherwise, it returns
-      ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
-      ++ and the yi's form a basis for the rational solutions of the
-      ++ homogeneous equation.
-    ratDsolve: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
-      ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
-      ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
-      ++ is of the form \spad{d1 h1 + ... + dq hq} where
-      ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
-    indicialEquationAtInfinity: LODO -> UP
-      ++ indicialEquationAtInfinity op returns the indicial equation of
-      ++ \spad{op} at infinity.
-    indicialEquationAtInfinity: LODO2 -> UP
-      ++ indicialEquationAtInfinity op returns the indicial equation of
-      ++ \spad{op} at infinity.
-
-  Implementation ==> add
-    import BoundIntegerRoots(F, UP)
-    import RationalIntegration(F, UP)
-    import PrimitiveRatDE(F, UP, LODO2, LODO)
-    import LinearSystemMatrixPackage(F, V, V, M)
-    import InnerCommonDenominator(UP, RF, List UP, List RF)
-
-    nzero?             : V -> Boolean
-    evenodd            : N -> F
-    UPfact             : N -> UP
-    infOrder           : RF -> Z
-    infTau             : (UP, N) -> F
-    infBound           : (LODO2, List RF) -> N
-    regularPoint       : (LODO2, List RF) -> Z
-    infIndicialEquation: (List N, List UP) -> UP
-    makeDot            : (Vector F, List RF) -> RF
-    unitlist           : (N, N) -> List F
-    infMuLambda: LODO2 -> Record(mu:Z, lambda:List N, func:List UP)
-    ratDsolve0: (LODO2, RF) -> Record(particular: U, basis: List RF)
-    ratDsolve1: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
-    candidates: (LODO2,List RF,UP) -> Record(basis:List RF,particular:List RF)
-
-    dummy := new()$Symbol
-
-    infOrder f == (degree denom f) - (degree numer f)
-    evenodd n  == (even? n => 1; -1)
-
-    ratDsolve1(op, lg) ==
-      d := denomLODE(op, lg)
-      rec := candidates(op, lg, d)
-      l := concat([op q for q in rec.basis],
-                  [op(rec.particular.i) - lg.i for i in 1..#(rec.particular)])
-      sys1 := reducedSystem(matrix [l])@Matrix(UP)
-      [rec.basis, reducedSystem sys1]
-
-    ratDsolve0(op, g) ==
-      zero? degree op => [inv(leadingCoefficient(op)::RF) * g, empty()]
-      minimumDegree op > 0 =>
-        sol := ratDsolve0(monicRightDivide(op, monomial(1, 1)).quotient, g)
-        b:List(RF) := [1]
-        for f in sol.basis repeat
-          if (uu := infieldint f) case RF then b := concat(uu::RF, b)
-        sol.particular case "failed" => ["failed", b]
-        [infieldint(sol.particular::RF), b]
-      (u := denomLODE(op, g)) case "failed" => ["failed", empty()]
-      rec := candidates(op, [g], u::UP)
-      l := lb := lsol := empty()$List(RF)
-      for q in rec.basis repeat
-          if zero?(opq := op q) then lsol := concat(q, lsol)
-          else (l := concat(opq, l); lb := concat(q, lb))
-      h:RF := (zero? g => 0; first(rec.particular))
-      empty? l =>
-          zero? g => [0, lsol]
-          [(g = op h => h; "failed"), lsol]
-      m:M
-      v:V
-      if zero? g then
-          m := reducedSystem(reducedSystem(matrix [l])@Matrix(UP))@M
-          v := new(ncols m, 0)$V
-      else
-          sys1 := reducedSystem(matrix [l], vector [g - op h]
-                               )@Record(mat: Matrix UP, vec: Vector UP)
-          sys2 := reducedSystem(sys1.mat, sys1.vec)@Record(mat:M, vec:V)
-          m := sys2.mat
-          v := sys2.vec
-      sol := solve(m, v)
-      part:U :=
-        zero? g => 0
-        sol.particular case "failed" => "failed"
-        makeDot(sol.particular::V, lb) + first(rec.particular)
-      [part,
-       concat_!(lsol, [makeDot(v, lb) for v in sol.basis | nzero? v])]
-
-    indicialEquationAtInfinity(op:LODO2) ==
-      rec := infMuLambda op
-      infIndicialEquation(rec.lambda, rec.func)
-
-    indicialEquationAtInfinity(op:LODO) ==
-      rec := splitDenominator(op, empty())
-      indicialEquationAtInfinity(rec.eq)
-
-    regularPoint(l, lg) ==
-      a := leadingCoefficient(l) * commonDenominator lg
-      coefficient(a, 0) ^= 0 => 0
-      for i in 1.. repeat
-        a(j := i::F) ^= 0 => return i
-        a(-j) ^= 0 => return(-i)
-
-    unitlist(i, q) ==
-      v := new(q, 0)$Vector(F)
-      v.i := 1
-      parts v
-
-    candidates(op, lg, d) ==
-      n := degree d + infBound(op, lg)
-      m := regularPoint(op, lg)
-      uts := UnivariateTaylorSeries(F, dummy, m::F)
-      tools := UTSodetools(F, UP, LODO2, uts)
-      solver := UnivariateTaylorSeriesODESolver(F, uts)
-      dd := UP2UTS(d)$tools
-      f := LODO2FUN(op)$tools
-      q := degree op
-      e := unitlist(1, q)
-      hom := [UTS2UP(dd * ode(f, unitlist(i, q))$solver, n)$tools /$RF d
-                   for i in 1..q]$List(RF)
-      a1 := inv(leadingCoefficient(op)::RF)
-      part := [UTS2UP(dd * ode(RF2UTS(a1 * g)$tools + f #1, e)$solver, n)$tools
-                /$RF d for g in lg | g ^= 0]$List(RF)
-      [hom, part]
-
-    nzero? v ==
-      for i in minIndex v .. maxIndex v repeat
-        not zero? qelt(v, i) => return true
-      false
-
--- returns z(z+1)...(z+(n-1))
-    UPfact n ==
-      zero? n => 1
-      z := monomial(1, 1)$UP
-      */[z + i::F::UP for i in 0..(n-1)::N]
-
-    infMuLambda l ==
-      lamb:List(N) := [d := degree l]
-      lf:List(UP) := [a := leadingCoefficient l]
-      mup := degree(a)::Z - d
-      while (l := reductum l) ^= 0 repeat
-          a := leadingCoefficient l
-          if (m := degree(a)::Z - (d := degree l)) > mup then
-            mup := m
-            lamb := [d]
-            lf := [a]
-          else if (m = mup) then
-            lamb := concat(d, lamb)
-            lf := concat(a, lf)
-      [mup, lamb, lf]
-
-    infIndicialEquation(lambda, lf) ==
-      ans:UP := 0
-      for i in lambda for f in lf repeat
-        ans := ans + evenodd i * leadingCoefficient f * UPfact i
-      ans
-
-    infBound(l, lg) ==
-      rec := infMuLambda l
-      n := min(- degree(l)::Z - 1,
-               integerBound infIndicialEquation(rec.lambda, rec.func))
-      while not(empty? lg) and zero? first lg repeat lg := rest lg
-      empty? lg => (-n)::N
-      m := infOrder first lg
-      for g in rest lg repeat
-        if not(zero? g) and (mm := infOrder g) < m then m := mm
-      (-min(n, rec.mu - degree(leadingCoefficient l)::Z + m))::N
-
-    makeDot(v, bas) ==
-      ans:RF := 0
-      for i in 1.. for b in bas repeat ans := ans + v.i::UP * b
-      ans
-
-    ratDsolve(op:LODO, g:RF) ==
-      rec := splitDenominator(op, [g])
-      ratDsolve0(rec.eq, first(rec.rh))
-
-    ratDsolve(op:LODO, lg:List RF) ==
-      rec := splitDenominator(op, lg)
-      ratDsolve1(rec.eq, rec.rh)
-
-    ratDsolve(op:LODO2, g:RF) ==
-      unit?(c := content op) => ratDsolve0(op, g)
-      ratDsolve0((op exquo c)::LODO2, inv(c::RF) * g)
-
-    ratDsolve(op:LODO2, lg:List RF) ==
-      unit?(c := content op) => ratDsolve1(op, lg)
-      ratDsolve1((op exquo c)::LODO2, [inv(c::RF) * g for g in lg])
-
-@
-\section{package ODETOOLS ODETools}
-<<package ODETOOLS ODETools>>=
-)abbrev package ODETOOLS ODETools
-++ Author: Manuel Bronstein
-++ Date Created: 20 March 1991
-++ Date Last Updated: 2 February 1994
-++ Description:
-++   \spad{ODETools} provides tools for the linear ODE solver.
-ODETools(F, LODO): Exports == Implementation where
-  N ==> NonNegativeInteger
-  L ==> List F
-  V ==> Vector F
-  M ==> Matrix F
-
-  F:    Field
-  LODO: LinearOrdinaryDifferentialOperatorCategory F
-
-  Exports ==> with
-    wronskianMatrix: L -> M
-      ++ wronskianMatrix([f1,...,fn]) returns the \spad{n x n} matrix m
-      ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
-    wronskianMatrix: (L, N) -> M
-      ++ wronskianMatrix([f1,...,fn], q, D) returns the \spad{q x n} matrix m
-      ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
-    variationOfParameters: (LODO, F, L) -> Union(V, "failed")
-      ++ variationOfParameters(op, g, [f1,...,fm])
-      ++ returns \spad{[u1,...,um]} such that a particular solution of the
-      ++ equation \spad{op y = g} is \spad{f1 int(u1) + ... + fm int(um)}
-      ++ where \spad{[f1,...,fm]} are linearly independent and \spad{op(fi)=0}.
-      ++ The value "failed" is returned if \spad{m < n} and no particular
-      ++ solution is found.
-    particularSolution: (LODO, F, L, F -> F) -> Union(F, "failed")
-      ++ particularSolution(op, g, [f1,...,fm], I) returns a particular
-      ++ solution h of the equation \spad{op y = g} where \spad{[f1,...,fm]}
-      ++ are linearly independent and \spad{op(fi)=0}.
-      ++ The value "failed" is returned if no particular solution is found.
-      ++ Note: the method of variations of parameters is used.
-
-  Implementation ==> add
-    import LinearSystemMatrixPackage(F, V, V, M)
-
-    diff := D()$LODO
-
-    wronskianMatrix l == wronskianMatrix(l, #l)
-
-    wronskianMatrix(l, q) ==
-      v:V := vector l
-      m:M := zero(q, #v)
-      for i in minRowIndex m .. maxRowIndex m repeat
-        setRow_!(m, i, v)
-        v := map_!(diff #1, v)
-      m
-
-    variationOfParameters(op, g, b) ==
-      empty? b => "failed"
-      v:V := new(n := degree op, 0)
-      qsetelt_!(v, maxIndex v, g / leadingCoefficient op)
-      particularSolution(wronskianMatrix(b, n), v)
-
-    particularSolution(op, g, b, integration) ==
-      zero? g => 0
-      (sol := variationOfParameters(op, g, b)) case "failed" => "failed"
-      ans:F := 0
-      for f in b for i in minIndex(s := sol::V) .. repeat
-        ans := ans + integration(qelt(s, i)) * f
-      ans
-
-@
-\section{package ODEINT ODEIntegration}
-<<package ODEINT ODEIntegration>>=
-)abbrev package ODEINT ODEIntegration
-++ Author: Manuel Bronstein
-++ Date Created: 4 November 1991
-++ Date Last Updated: 2 February 1994
-++ Description:
-++ \spadtype{ODEIntegration} provides an interface to the integrator.
-++ This package is intended for use
-++ by the differential equations solver but not at top-level.
-ODEIntegration(R, F): Exports == Implementation where
-  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
-          LinearlyExplicitRingOver Integer, CharacteristicZero)
-  F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
-                                              PrimitiveFunctionCategory)
-
-  Q   ==> Fraction Integer
-  UQ  ==> Union(Q, "failed")
-  SY  ==> Symbol
-  K   ==> Kernel F
-  P   ==> SparseMultivariatePolynomial(R, K)
-  REC ==> Record(coef:Q, logand:F)
-
-  Exports ==> with
-    int   : (F, SY) -> F
-      ++ int(f, x) returns the integral of f with respect to x.
-    expint: (F, SY) -> F
-      ++ expint(f, x) returns e^{the integral of f with respect to x}.
-    diff  : SY -> (F -> F)
-      ++ diff(x) returns the derivation with respect to x.
-
-  Implementation ==> add
-    import FunctionSpaceIntegration(R, F)
-    import ElementaryFunctionStructurePackage(R, F)
-
-    isQ   : List F -> UQ
-    isQlog: F -> Union(REC, "failed")
-    mkprod: List REC -> F
-
-    diff x == differentiate(#1, x)
-
--- This is the integration function to be used for quadratures
-    int(f, x) ==
-      (u := integrate(f, x)) case F => u::F
-      first(u::List(F))
-
--- mkprod([q1, f1],...,[qn,fn]) returns */(fi^qi) but groups the
--- qi having the same denominator together
-    mkprod l ==
-      empty? l => 1
-      rec := first l
-      d := denom(rec.coef)
-      ll := select(denom(#1.coef) = d, l)
-      nthRoot(*/[r.logand ** numer(r.coef) for r in ll], d) *
-        mkprod setDifference(l, ll)
-
--- computes exp(int(f,x)) in a non-naive way
-    expint(f, x) ==
-      a := int(f, x)
-      (u := validExponential(tower a, a, x)) case F => u::F
-      da := denom a
-      l :=
-        (v := isPlus(na := numer a)) case List(P) => v::List(P)
-        [na]
-      exponent:P := 0
-      lrec:List(REC) := empty()
-      for term in l repeat
-        if (w := isQlog(term / da)) case REC then
-          lrec := concat(w::REC, lrec)
-        else
-          exponent := exponent + term
-      mkprod(lrec) * exp(exponent / da)
-
--- checks if all the elements of l are rational numbers, returns their product
-    isQ l ==
-      prod:Q := 1
-      for x in l repeat
-        (u := retractIfCan(x)@UQ) case "failed" => return "failed"
-        prod := prod * u::Q
-      prod
-
--- checks if a non-sum expr is of the form c * log(g) for a rational number c
-    isQlog f ==
-      is?(f, "log"::SY) => [1, first argument(retract(f)@K)]
-      (v := isTimes f) case List(F) and (#(l := v::List(F)) <= 3) =>
-          l := reverse_! sort_! l
-          is?(first l, "log"::SY) and ((u := isQ rest l) case Q) =>
-              [u::Q, first argument(retract(first(l))@K)]
-          "failed"
-      "failed"
-
-@
-\section{package ODECONST ConstantLODE}
-<<package ODECONST ConstantLODE>>=
-)abbrev package ODECONST ConstantLODE
-++ Author: Manuel Bronstein
-++ Date Created: 18 March 1991
-++ Date Last Updated: 3 February 1994
-++ Description: Solution of linear ordinary differential equations, constant coefficient case.
-ConstantLODE(R, F, L): Exports == Implementation where
-  R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
-          LinearlyExplicitRingOver Integer, CharacteristicZero)
-  F: Join(AlgebraicallyClosedFunctionSpace R,
-          TranscendentalFunctionCategory, PrimitiveFunctionCategory)
-  L: LinearOrdinaryDifferentialOperatorCategory F
-
-  Z   ==> Integer
-  SY  ==> Symbol
-  K   ==> Kernel F
-  V   ==> Vector F
-  M   ==> Matrix F
-  SUP ==> SparseUnivariatePolynomial F
-
-  Exports ==> with
-    constDsolve: (L, F, SY) -> Record(particular:F, basis:List F)
-      ++ constDsolve(op, g, x) returns \spad{[f, [y1,...,ym]]}
-      ++ where f is a particular solution of the equation \spad{op y = g},
-      ++ and the \spad{yi}'s form a basis for the solutions of \spad{op y = 0}.
-
-  Implementation ==> add
-    import ODETools(F, L)
-    import ODEIntegration(R, F)
-    import ElementaryFunctionSign(R, F)
-    import AlgebraicManipulations(R, F)
-    import FunctionSpaceIntegration(R, F)
-    import FunctionSpaceUnivariatePolynomialFactor(R, F, SUP)
-
-    homoBasis: (L, F) -> List F
-    quadSol  : (SUP, F) -> List F
-    basisSqfr: (SUP, F) -> List F
-    basisSol : (SUP, Z, F) -> List F
-
-    constDsolve(op, g, x) ==
-      b := homoBasis(op, x::F)
-      [particularSolution(op, g, b, int(#1, x))::F, b]
-
-    homoBasis(op, x) ==
-      p:SUP := 0
-      while op ^= 0 repeat
-          p  := p + monomial(leadingCoefficient op, degree op)
-          op := reductum op
-      b:List(F) := empty()
-      for ff in factors ffactor p repeat
-        b := concat_!(b, basisSol(ff.factor, dec(ff.exponent), x))
-      b
-
-    basisSol(p, n, x) ==
-      l := basisSqfr(p, x)
-      zero? n => l
-      ll := copy l
-      xn := x::F
-      for i in 1..n repeat
-        l := concat_!(l, [xn * f for f in ll])
-        xn := x * xn
-      l
-
-    basisSqfr(p, x) ==
---      one?(d := degree p) =>
-      ((d := degree p) = 1) =>
-        [exp(- coefficient(p, 0) * x / leadingCoefficient p)]
-      d = 2 => quadSol(p, x)
-      [exp(a * x) for a in rootsOf p]
-
-    quadSol(p, x) ==
-      (u := sign(delta := (b := coefficient(p, 1))**2 - 4 *
-        (a := leadingCoefficient p) * (c := coefficient(p, 0))))
-          case Z and negative?(u::Z) =>
-            y := x / (2 * a)
-            r := - b * y
-            i := rootSimp(sqrt(-delta)) * y
-            [exp(r) * cos(i), exp(r) * sin(i)]
-      [exp(a * x) for a in zerosOf 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>>
-
--- Compile order for the differential equation solver:
--- oderf.spad  odealg.spad  nlode.spad  nlinsol.spad  riccati.spad  odeef.spad
-
-<<package BALFACT BalancedFactorisation>>
-<<package BOUNDZRO BoundIntegerRoots>>
-<<package ODEPRIM PrimitiveRatDE>>
-<<package UTSODETL UTSodetools>>
-<<package ODERAT RationalLODE>>
-<<package ODETOOLS ODETools>>
-<<package ODEINT ODEIntegration>>
-<<package ODECONST ConstantLODE>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/omdev.spad.pamphlet b/src/algebra/omdev.spad.pamphlet
deleted file mode 100644
index bea83ea..0000000
--- a/src/algebra/omdev.spad.pamphlet
+++ /dev/null
@@ -1,132 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra omdev.spad}
-\author{Vilya Harvey}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package OMPKG OpenMathPackage}
-<<package OMPKG OpenMathPackage>>=
-)abbrev package OMPKG OpenMathPackage
-++ Author: Vilya Harvey
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: \spadtype{OpenMathPackage} provides some simple utilities 
-++ to make reading OpenMath objects easier.
-
-OpenMathPackage(): with
-  OMread            : OpenMathDevice -> Any
-  ++ OMread(dev) reads an OpenMath object from \axiom{dev} and passes it
-  ++ to AXIOM.
-  OMreadFile        : String -> Any
-  ++ OMreadFile(f) reads an OpenMath object from \axiom{f} and passes it
-  ++ to AXIOM.
-  OMreadStr         : String -> Any
-  ++ OMreadStr(f) reads an OpenMath object from \axiom{f} and passes it
-  ++ to AXIOM.
-  OMlistCDs         : () -> List(String)
-  ++ OMlistCDs() lists all the CDs supported by AXIOM.
-  OMlistSymbols     : String -> List(String)
-  ++ OMlistSymbols(cd) lists all the symbols in \axiom{cd}.
-  OMsupportsCD?      : String -> Boolean
-  ++ OMsupportsCD?(cd) returns true if AXIOM supports \axiom{cd}, false 
-  ++ otherwise.
-  OMsupportsSymbol? : (String, String) -> Boolean
-  ++ OMsupportsSymbol?(s,cd) returns true if AXIOM supports symbol \axiom{s}
-  ++ from CD \axiom{cd}, false otherwise.
-  OMunhandledSymbol : (String, String) -> Exit
-  ++ OMunhandledSymbol(s,cd) raises an error if AXIOM reads a symbol which it
-  ++ is unable to handle.  Note that this is different from an unexpected
-  ++ symbol.
- == add
-  import OpenMathEncoding
-  import OpenMathDevice
-  import String
-
-  OMunhandledSymbol(u,v) ==
-    error concat ["AXIOM is unable to process the symbol ",u," from CD ",v,"."]
-
-  OMread(dev: OpenMathDevice): Any ==
-    interpret(OM_-READ(dev)$Lisp :: InputForm)
-
-  OMreadFile(filename: String): Any ==
-    dev := OMopenFile(filename, "r", OMencodingUnknown())
-    res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
-    OMclose(dev)
-    res
-
-  OMreadStr(str: String): Any ==
-    strp := OM_-STRINGTOSTRINGPTR(str)$Lisp
-    dev := OMopenString(strp pretend String, OMencodingUnknown())
-    res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
-    OMclose(dev)
-    res
-
-  OMlistCDs(): List(String) ==
-    OM_-LISTCDS()$Lisp pretend List(String)
-
-  OMlistSymbols(cd: String): List(String) ==
-    OM_-LISTSYMBOLS(cd)$Lisp pretend List(String)
-
-  import SExpression
-
-  OMsupportsCD?(cd: String): Boolean ==
-    not null? OM_-SUPPORTSCD(cd)$Lisp 
-
-  OMsupportsSymbol?(cd: String, name: String): Boolean ==
-    not null? OM_-SUPPORTSSYMBOL(cd, name)$Lisp
-
-@
-\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 OMPKG OpenMathPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/omserver.spad.pamphlet b/src/algebra/omserver.spad.pamphlet
deleted file mode 100644
index de74896..0000000
--- a/src/algebra/omserver.spad.pamphlet
+++ /dev/null
@@ -1,120 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra omserver.spad}
-\author{Vilya Harvey}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package OMSERVER OpenMathServerPackage}
-<<package OMSERVER OpenMathServerPackage>>=
-)abbrev package OMSERVER OpenMathServerPackage
-++ Author: Vilya Harvey
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: \spadtype{OpenMathServerPackage} provides the necessary
-++ operations to run AXIOM as an OpenMath server, reading/writing objects
-++ to/from a port.  Please note the facilities available here are very basic.
-++ The idea is that a user calls e.g. \axiom{Omserve(4000,60)} and then
-++ another process sends OpenMath objects to port 4000 and reads the result.
-
-OpenMathServerPackage(): with
-  OMreceive : OpenMathConnection -> Any
-  ++ OMreceive(c) reads an OpenMath object from connection \axiom{c} and
-  ++ returns the appropriate AXIOM object.
-  OMsend    : (OpenMathConnection, Any) -> Void
-  ++ OMsend(c,u) attempts to output \axiom{u} on \axiom{c} in OpenMath.
-  OMserve   : (SingleInteger, SingleInteger) -> Void
-  ++ OMserve(portnum,timeout) puts AXIOM into server mode on port number
-  ++ \axiom{portnum}.  The parameter \axiom{timeout} specifies the timeout
-  ++ period for the connection.
- == add
-  import OpenMathDevice
-  import OpenMathConnection
-  import OpenMathPackage
-  import OpenMath
-
-
-
-  OMreceive(conn: OpenMathConnection): Any ==
-    dev: OpenMathDevice := OMconnInDevice(conn)
-    OMsetEncoding(dev, OMencodingUnknown);
-    OMread(dev)
-
-  OMsend(conn: OpenMathConnection, value: Any): Void ==
-    dev: OpenMathDevice := OMconnOutDevice(conn)
-    OMsetEncoding(dev, OMencodingXML);
-    --retractable?(value)$AnyFunctions1(Expression Integer) =>
-    --  OMwrite(dev, retract(value)$AnyFunctions1(Expression Integer), true)
-    retractable?(value)$AnyFunctions1(Integer) =>
-      OMwrite(dev, retract(value)$AnyFunctions1(Integer), true)
-    retractable?(value)$AnyFunctions1(Float) =>
-      OMwrite(dev, retract(value)$AnyFunctions1(Float), true)
-    retractable?(value)$AnyFunctions1(SingleInteger) =>
-      OMwrite(dev, retract(value)$AnyFunctions1(SingleInteger), true)
-    retractable?(value)$AnyFunctions1(DoubleFloat) =>
-      OMwrite(dev, retract(value)$AnyFunctions1(DoubleFloat), true)
-    retractable?(value)$AnyFunctions1(String) =>
-      OMwrite(dev, retract(value)$AnyFunctions1(String), true)
-
-  OMserve(portNum: SingleInteger, timeout: SingleInteger): Void ==
-    conn: OpenMathConnection := OMmakeConn(timeout)
-    OMbindTCP(conn, portNum)
-    val: Any
-    while true repeat
-      val := OMreceive(conn)
-      OMsend(conn, val)
-
-@
-\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 OMSERVER OpenMathServerPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/op.spad.pamphlet b/src/algebra/op.spad.pamphlet
deleted file mode 100644
index ed28ee3..0000000
--- a/src/algebra/op.spad.pamphlet
+++ /dev/null
@@ -1,362 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra op.spad}
-\author{Manuel Bronstein}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package BOP1 BasicOperatorFunctions1}
-<<package BOP1 BasicOperatorFunctions1>>=
-)abbrev package BOP1 BasicOperatorFunctions1
-++ Tools to set/get common properties of operators
-++ Author: Manuel Bronstein
-++ Date Created: 28 Mar 1988
-++ Date Last Updated: 15 May 1990
-++ Description:
-++   This package exports functions to set some commonly used properties
-++   of operators, including properties which contain functions.
-++ Keywords: operator.
-BasicOperatorFunctions1(A:SetCategory): Exports == Implementation where
-  OP   ==> BasicOperator
-  EVAL    ==> "%eval"
-  CONST   ==> "%constant"
-  DIFF    ==> "%diff"
-
-  Exports ==> with
-    evaluate        : (OP, List A)      -> Union(A, "failed")
-      ++ evaluate(op, [a1,...,an]) checks if op has an "%eval"
-      ++ property f. If it has, then \spad{f(a1,...,an)} is returned, and
-      ++ "failed" otherwise.
-    evaluate        : (OP, List A -> A) -> OP
-      ++ evaluate(op, foo) attaches foo as the "%eval" property
-      ++ of op. If op has an "%eval" property f, then applying op
-      ++ to \spad{(a1,...,an)} returns the result of \spad{f(a1,...,an)}.
-    evaluate        : (OP, A -> A)      -> OP
-      ++ evaluate(op, foo) attaches foo as the "%eval" property
-      ++ of op. If op has an "%eval" property f, then applying op
-      ++ to a returns the result of \spad{f(a)}. Argument op must be unary.
-    evaluate        : OP                -> Union(List A -> A, "failed")
-      ++ evaluate(op) returns the value of the "%eval" property of
-      ++ op if it has one, and "failed" otherwise.
-    derivative      : (OP, List (List A -> A)) -> OP
-      ++ derivative(op, [foo1,...,foon]) attaches [foo1,...,foon] as
-      ++ the "%diff" property of op. If op has an "%diff" property
-      ++ \spad{[f1,...,fn]} then applying a derivation D to \spad{op(a1,...,an)}
-      ++ returns \spad{f1(a1,...,an) * D(a1) + ... + fn(a1,...,an) * D(an)}.
-    derivative      : (OP, A -> A) -> OP
-      ++ derivative(op, foo) attaches foo as the "%diff" property
-      ++ of op. If op has an "%diff" property f, then applying a
-      ++ derivation D to op(a) returns \spad{f(a) * D(a)}. Argument op must be unary.
-    derivative      : OP -> Union(List(List A -> A), "failed")
-      ++ derivative(op) returns the value of the "%diff" property of
-      ++ op if it has one, and "failed" otherwise.
-    if A has OrderedSet then
-      constantOperator: A -> OP
-        ++ constantOperator(a) returns a nullary operator op
-        ++ such that \spad{op()} always evaluate to \spad{a}.
-      constantOpIfCan : OP -> Union(A, "failed")
-        ++ constantOpIfCan(op) returns \spad{a} if op is the constant
-        ++ nullary operator always returning \spad{a}, "failed" otherwise.
-
-  Implementation ==> add
-    evaluate(op:OP, func:A -> A) == evaluate(op, func first #1)
-
-    evaluate op ==
-      (func := property(op, EVAL)) case "failed" => "failed"
-      (func::None) pretend (List A -> A)
-
-    evaluate(op:OP, args:List A) ==
-      (func := property(op, EVAL)) case "failed" => "failed"
-      ((func::None) pretend (List A -> A)) args
-
-    evaluate(op:OP, func:List A -> A) ==
-      setProperty(op, EVAL, func pretend None)
-
-    derivative op ==
-      (func := property(op, DIFF)) case "failed" => "failed"
-      ((func::None) pretend List(List A -> A))
-
-    derivative(op:OP, grad:List(List A -> A)) ==
-      setProperty(op, DIFF, grad pretend None)
-
-    derivative(op:OP, f:A -> A) ==
-      unary? op or nary? op =>
-        derivative(op, [f first #1]$List(List A -> A))
-      error "Operator is not unary"
-
-    if A has OrderedSet then
-      cdisp   : (OutputForm, List OutputForm) -> OutputForm
-      csex    : (InputForm,  List InputForm) -> InputForm
-      eqconst?: (OP, OP) -> Boolean
-      ltconst?: (OP, OP) -> Boolean
-      constOp : A -> OP
-
-      opconst:OP :=
-        comparison(equality(operator("constant"::Symbol, 0), eqconst?),
-                                                               ltconst?)
-
-      cdisp(a, l) == a
-      csex(a, l)  == a
-
-      eqconst?(a, b) ==
-        (va := property(a, CONST)) case "failed" => not has?(b, CONST)
-        ((vb := property(b, CONST)) case None) and
-           ((va::None) pretend A) = ((vb::None) pretend A)
-
-      ltconst?(a, b) ==
-        (va := property(a, CONST)) case "failed" => has?(b, CONST)
-        ((vb := property(b, CONST)) case None) and
-           ((va::None) pretend A) < ((vb::None) pretend A)
-
-      constOp a ==
-        setProperty(display(copy opconst, cdisp(a::OutputForm, #1)),
-                                                  CONST, a pretend None)
-
-      constantOpIfCan op ==
-        is?(op, "constant"::Symbol) and
-          ((u := property(op, CONST)) case None) => (u::None) pretend A
-        "failed"
-
-      if A has ConvertibleTo InputForm then
-        constantOperator a == input(constOp a, csex(convert a, #1))
-      else
-        constantOperator a == constOp a
-
-@
-\section{package COMMONOP CommonOperators}
-<<package COMMONOP CommonOperators>>=
-)abbrev package COMMONOP CommonOperators
-++ Provides commonly used operators
-++ Author: Manuel Bronstein
-++ Date Created: 25 Mar 1988
-++ Date Last Updated: 2 December 1994
-++ Description:
-++ This package exports the elementary operators, with some semantics
-++ already attached to them. The semantics that is attached here is not
-++ dependent on the set in which the operators will be applied.
-++ Keywords: operator.
-CommonOperators(): Exports == Implementation where
-  OP  ==> BasicOperator
-  O   ==> OutputForm
-  POWER ==> "%power"::Symbol
-  ALGOP ==> "%alg"
-  EVEN  ==> "even"
-  ODD   ==> "odd"
-  DUMMYVAR ==> "%dummyVar"
-
-  Exports ==> with
-    operator: Symbol -> OP
-        ++ operator(s) returns an operator with name s, with the
-        ++ appropriate semantics if s is known. If s is not known,
-        ++ the result has no semantics.
-
-  Implementation ==> add
-    dpi        : List O -> O
-    dgamma     : List O -> O
-    dquote     : List O -> O
-    dexp       : O -> O
-    dfact      : O -> O
-    startUp    : Boolean -> Void
-    setDummyVar: (OP, NonNegativeInteger) -> OP
-
-    brandNew?:Reference(Boolean) := ref true
-
-    opalg   := operator("rootOf"::Symbol, 2)$OP
-    oproot  := operator("nthRoot"::Symbol, 2)
-    oppi    := operator("pi"::Symbol, 0)
-    oplog   := operator("log"::Symbol, 1)
-    opexp   := operator("exp"::Symbol, 1)
-    opabs   := operator("abs"::Symbol, 1)
-    opsin   := operator("sin"::Symbol, 1)
-    opcos   := operator("cos"::Symbol, 1)
-    optan   := operator("tan"::Symbol, 1)
-    opcot   := operator("cot"::Symbol, 1)
-    opsec   := operator("sec"::Symbol, 1)
-    opcsc   := operator("csc"::Symbol, 1)
-    opasin  := operator("asin"::Symbol, 1)
-    opacos  := operator("acos"::Symbol, 1)
-    opatan  := operator("atan"::Symbol, 1)
-    opacot  := operator("acot"::Symbol, 1)
-    opasec  := operator("asec"::Symbol, 1)
-    opacsc  := operator("acsc"::Symbol, 1)
-    opsinh  := operator("sinh"::Symbol, 1)
-    opcosh  := operator("cosh"::Symbol, 1)
-    optanh  := operator("tanh"::Symbol, 1)
-    opcoth  := operator("coth"::Symbol, 1)
-    opsech  := operator("sech"::Symbol, 1)
-    opcsch  := operator("csch"::Symbol, 1)
-    opasinh := operator("asinh"::Symbol, 1)
-    opacosh := operator("acosh"::Symbol, 1)
-    opatanh := operator("atanh"::Symbol, 1)
-    opacoth := operator("acoth"::Symbol, 1)
-    opasech := operator("asech"::Symbol, 1)
-    opacsch := operator("acsch"::Symbol, 1)
-    opbox   := operator("%box"::Symbol)$OP
-    oppren  := operator("%paren"::Symbol)$OP
-    opquote := operator("applyQuote"::Symbol)$OP
-    opdiff  := operator("%diff"::Symbol, 3)
-    opsi    := operator("Si"::Symbol, 1)
-    opci    := operator("Ci"::Symbol, 1)
-    opei    := operator("Ei"::Symbol, 1)
-    opli    := operator("li"::Symbol, 1)
-    operf   := operator("erf"::Symbol, 1)
-    opli2   := operator("dilog"::Symbol, 1)
-    opGamma     := operator("Gamma"::Symbol, 1)
-    opGamma2    := operator("Gamma2"::Symbol, 2)
-    opBeta      := operator("Beta"::Symbol, 2)
-    opdigamma   := operator("digamma"::Symbol, 1)
-    oppolygamma := operator("polygamma"::Symbol, 2)
-    opBesselJ   := operator("besselJ"::Symbol, 2)
-    opBesselY   := operator("besselY"::Symbol, 2)
-    opBesselI   := operator("besselI"::Symbol, 2)
-    opBesselK   := operator("besselK"::Symbol, 2)
-    opAiryAi    := operator("airyAi"::Symbol,  1)
-    opAiryBi    := operator("airyBi"::Symbol , 1)
-    opint   := operator("integral"::Symbol, 3)
-    opdint  := operator("%defint"::Symbol, 5)
-    opfact  := operator("factorial"::Symbol, 1)
-    opperm  := operator("permutation"::Symbol, 2)
-    opbinom := operator("binomial"::Symbol, 2)
-    oppow   := operator(POWER, 2)
-    opsum   := operator("summation"::Symbol, 3)
-    opdsum  := operator("%defsum"::Symbol, 5)
-    opprod  := operator("product"::Symbol, 3)
-    opdprod := operator("%defprod"::Symbol, 5)
-
-    algop   := [oproot, opalg]$List(OP)
-    rtrigop := [opsin, opcos, optan, opcot, opsec, opcsc,
-                         opasin, opacos, opatan, opacot, opasec, opacsc]
-    htrigop := [opsinh, opcosh, optanh, opcoth, opsech, opcsch,
-                   opasinh, opacosh, opatanh, opacoth, opasech, opacsch]
-    trigop  := concat(rtrigop, htrigop)
-    elemop  := concat(trigop, [oppi, oplog, opexp])
-    primop  := [opei, opli, opsi, opci, operf, opli2, opint, opdint]
-    combop  := [opfact, opperm, opbinom, oppow,
-                                         opsum, opdsum, opprod, opdprod]
-    specop  := [opGamma, opGamma2, opBeta, opdigamma, oppolygamma, opabs,
-                opBesselJ, opBesselY, opBesselI, opBesselK, opAiryAi,
-                 opAiryBi]
-    anyop   := [oppren, opdiff, opbox, opquote]
-    allop   := concat(concat(concat(concat(concat(
-                            algop,elemop),primop),combop),specop),anyop)
-
--- odd and even operators, must be maintained current!
-    evenop := [opcos, opsec, opcosh, opsech, opabs]
-    oddop  := [opsin, opcsc, optan, opcot, opasin, opacsc, opatan,
-               opsinh, opcsch, optanh, opcoth, opasinh, opacsch,opatanh,opacoth,
-                opsi, operf]
-
--- operators whose second argument is a dummy variable
-    dummyvarop1 := [opdiff,opalg, opint, opsum, opprod]
--- operators whose second and third arguments are dummy variables
-    dummyvarop2 := [opdint, opdsum, opdprod]
-
-    operator s ==
-      if (deref brandNew?) then startUp false
-      for op in allop repeat
-        is?(op, s) => return copy op
-      operator(s)$OP
-
-    dpi l    == "%pi"::Symbol::O
-    dfact x  == postfix("!"::Symbol::O, (ATOM(x)$Lisp => x; paren x))
-    dquote l == prefix(quote(first(l)::O), rest l)
-    dgamma l == prefix(hconcat("|"::Symbol::O, overbar(" "::Symbol::O)), l)
-    setDummyVar(op, n) == setProperty(op, DUMMYVAR, n pretend None)
-
-    dexp x ==
-      e := "%e"::Symbol::O
-      x = 1::O => e
-      e ** x
-
-    startUp b ==
-      brandNew?() := b
-      display(oppren, paren)
-      display(opbox, commaSeparate)
-      display(oppi, dpi)
-      display(opexp, dexp)
-      display(opGamma, dgamma)
-      display(opGamma2, dgamma)
-      display(opfact, dfact)
-      display(opquote, dquote)
-      display(opperm, supersub("A"::Symbol::O, #1))
-      display(opbinom, binomial(first #1, second #1))
-      display(oppow, first(#1) ** second(#1))
-      display(opsum,   sum(first #1, second #1, third #1))
-      display(opprod, prod(first #1, second #1, third #1))
-      display(opint, int(first #1 * hconcat("d"::Symbol::O, second #1),
-                                                   empty(), third #1))
-      input(oppren, convert concat(convert("("::Symbol)@InputForm,
-                            concat(#1, convert(")"::Symbol)@InputForm)))
-      input(oppow, convert concat(convert("**"::Symbol)@InputForm, #1))
-      input(oproot,
-            convert [convert("**"::Symbol)@InputForm, first #1, 1 / second #1])
-      for op in algop   repeat assert(op, ALGOP)
-      for op in rtrigop repeat assert(op, "rtrig")
-      for op in htrigop repeat assert(op, "htrig")
-      for op in trigop  repeat assert(op, "trig")
-      for op in elemop  repeat assert(op, "elem")
-      for op in primop  repeat assert(op, "prim")
-      for op in combop  repeat assert(op, "comb")
-      for op in specop  repeat assert(op, "special")
-      for op in anyop   repeat assert(op, "any")
-      for op in evenop  repeat assert(op, EVEN)
-      for op in oddop   repeat assert(op, ODD)
-      for op in dummyvarop1 repeat setDummyVar(op, 1)
-      for op in dummyvarop2 repeat setDummyVar(op, 2)
-      assert(oppren, "linear")
-      void
-
-@
-\section{License}
-<<license>>=
---Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
---All rights reserved.
---
---Redistribution and use in source and binary forms, with or without
---modification, are permitted provided that the following conditions are
---met:
---
---    - Redistributions of source code must retain the above copyright
---      notice, this list of conditions and the following disclaimer.
---
---    - Redistributions in binary form must reproduce the above copyright
---      notice, this list of conditions and the following disclaimer in
---      the documentation and/or other materials provided with the
---      distribution.
---
---    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
---      names of its contributors may be used to endorse or promote products
---      derived from this software without specific prior written permission.
---
---THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
---IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
---TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
---PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
---OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
---EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
---PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
---PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
---LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
---NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
---SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-@
-<<*>>=
-<<license>>
-
--- SPAD files for the functional world should be compiled in the
--- following order:
---
---   OP  kl  expr function
-
-<<package BOP1 BasicOperatorFunctions1>>
-<<package COMMONOP CommonOperators>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/openmath.spad.pamphlet b/src/algebra/openmath.spad.pamphlet
deleted file mode 100644
index 2ad5718..0000000
--- a/src/algebra/openmath.spad.pamphlet
+++ /dev/null
@@ -1,331 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra openmath.spad}
-\author{Mike Dewar, Vilya Harvey}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package OMEXPR ExpressionToOpenMath}
-<<package OMEXPR ExpressionToOpenMath>>=
-)abbrev package OMEXPR ExpressionToOpenMath
-++ Author: Mike Dewar & Vilya Harvey
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: \spadtype{ExpressionToOpenMath} provides support for
-++ converting objects of type \spadtype{Expression} into OpenMath.
-ExpressionToOpenMath(R: Join(OpenMath, OrderedSet, Ring)): with
-  OMwrite  : Expression R -> String
-  OMwrite  : (Expression R, Boolean) -> String
-  OMwrite  : (OpenMathDevice, Expression R) -> Void
-  OMwrite  : (OpenMathDevice, Expression R, Boolean) -> Void
- == add
-  import Expression R
-  SymInfo ==> Record(cd:String, name:String)
-  import SymInfo
-  import Record(key: Symbol, entry: SymInfo)
-  import AssociationList(Symbol, SymInfo)
-  import OMENC
-
-  ----------------------------
-  -- Local translation tables.
-  ----------------------------
-
-  nullaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
-    [pi, ["nums1", "pi"]] ]
-
-  unaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
-    [exp,  ["transc1", "exp"]],_
-    [log,  ["transc1", "ln"]],_
-    [sin,  ["transc1", "sin"]],_
-    [cos,  ["transc1", "cos"]],_
-    [tan,  ["transc1", "tan"]],_
-    [cot,  ["transc1", "cot"]],_
-    [sec,  ["transc1", "sec"]],_
-    [csc,  ["transc1", "csc"]],_
-    [asin, ["transc1", "arcsin"]],_
-    [acos, ["transc1", "arccos"]],_
-    [atan, ["transc1", "arctan"]],_
-    [acot, ["transc1", "arccot"]],_
-    [asec, ["transc1", "arcsec"]],_
-    [acsc, ["transc1", "arccsc"]],_
-    [sinh, ["transc1", "sinh"]],_
-    [cosh, ["transc1", "cosh"]],_
-    [tanh, ["transc1", "tanh"]],_
-    [coth, ["transc1", "coth"]],_
-    [sech, ["transc1", "sech"]],_
-    [csch, ["transc1", "csch"]],_
-    [asinh, ["transc1", "arcsinh"]],_
-    [acosh, ["transc1", "arccosh"]],_
-    [atanh, ["transc1", "arctanh"]],_
-    [acoth, ["transc1", "arccoth"]],_
-    [asech, ["transc1", "arcsech"]],_
-    [acsch, ["transc1", "arccsch"]],_
-    [factorial, ["integer1", "factorial"]],_
-    [abs, ["arith1", "abs"]] ]
-
-    -- Still need the following unary functions:
-    --  digamma
-    --  Gamma
-    --  airyAi
-    --  airyBi
-    --  erf
-    --  Ei
-    --  Si
-    --  Ci
-    --  li
-    --  dilog
-
-    -- Still need the following binary functions:
-    --      Gamma(a, x)
-    --      Beta(x,y) 
-    --      polygamma(k,x)
-    --      besselJ(v,x)
-    --      besselY(v,x)
-    --      besselI(v,x)
-    --      besselK(v,x)
-    --      permutation(n, m)
-    --      summation(x:%, n:Symbol) : as opposed to "definite" sum
-    --      product(x:%, n:Symbol)   : ditto
-
-  ------------------------
-  -- Forward declarations.
-  ------------------------
-
-  outputOMExpr  : (OpenMathDevice, Expression R) -> Void
-
-  -------------------------
-  -- Local helper functions
-  -------------------------
-
-  outputOMArith1(dev: OpenMathDevice, sym: String, args: List Expression R): Void ==
-    OMputApp(dev)
-    OMputSymbol(dev, "arith1", sym)
-    for arg in args repeat
-      OMwrite(dev, arg, false)
-    OMputEndApp(dev)
-
-  outputOMLambda(dev: OpenMathDevice, ex: Expression R, var: Expression R): Void ==
-    OMputBind(dev)
-    OMputSymbol(dev, "fns1", "lambda")
-    OMputBVar(dev)
-    OMwrite(dev, var, false)
-    OMputEndBVar(dev)
-    OMwrite(dev, ex, false)
-    OMputEndBind(dev)
-
-  outputOMInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
-    OMputApp(dev)
-    OMputSymbol(dev, "interval1", "interval")
-    OMwrite(dev, lo, false)
-    OMwrite(dev, hi, false)
-    OMputEndApp(dev)
-
-  outputOMIntInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
-    OMputApp(dev)
-    OMputSymbol(dev, "interval1", "integer__interval")
-    OMwrite(dev, lo, false)
-    OMwrite(dev, hi, false)
-    OMputEndApp(dev)
-
-  outputOMBinomial(dev: OpenMathDevice, args: List Expression R): Void ==
-    not #args=2 => error "Wrong number of arguments to binomial"
-    OMputApp(dev)
-    OMputSymbol(dev, "combinat1", "binomial")
-    for arg in args repeat
-      OMwrite(dev, arg, false)
-    OMputEndApp(dev)
-
-  outputOMPower(dev: OpenMathDevice, args: List Expression R): Void ==
-    not #args=2 => error "Wrong number of arguments to power"
-    outputOMArith1(dev, "power", args)
-
-  outputOMDefsum(dev: OpenMathDevice, args: List Expression R): Void ==
-    #args ^= 5 => error "Unexpected number of arguments to a defsum"
-    OMputApp(dev)
-    OMputSymbol(dev, "arith1", "sum")
-    outputOMIntInterval(dev, args.4, args.5)
-    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
-    OMputEndApp(dev)
-
-  outputOMDefprod(dev: OpenMathDevice, args: List Expression R): Void ==
-    #args ^= 5 => error "Unexpected number of arguments to a defprod"
-    OMputApp(dev)
-    OMputSymbol(dev, "arith1", "product")
-    outputOMIntInterval(dev, args.4, args.5)
-    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
-    OMputEndApp(dev)
-
-  outputOMDefint(dev: OpenMathDevice, args: List Expression R): Void ==
-    #args ^= 5 => error "Unexpected number of arguments to a defint"
-    OMputApp(dev)
-    OMputSymbol(dev, "calculus1", "defint")
-    outputOMInterval(dev, args.4, args.5)
-    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
-    OMputEndApp(dev)
-
-  outputOMInt(dev: OpenMathDevice, args: List Expression R): Void ==
-    #args ^= 3 => error "Unexpected number of arguments to a defint"
-    OMputApp(dev)
-    OMputSymbol(dev, "calculus1", "int")
-    outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
-    OMputEndApp(dev)
-
-  outputOMFunction(dev: OpenMathDevice, op: Symbol, args: List Expression R): Void ==
-    nargs := #args
-    zero? nargs =>
-      omOp: Union(SymInfo, "failed") := search(op, nullaryFunctionAList)
-      omOp case "failed" =>
-        error concat ["No OpenMath definition for nullary function ", coerce op]
-      OMputSymbol(dev, omOp.cd, omOp.name)
---    one? nargs =>
-    (nargs = 1) =>
-      omOp: Union(SymInfo, "failed") := search(op, unaryFunctionAList)
-      omOp case "failed" =>
-        error concat ["No OpenMath definition for unary function ", coerce op]
-      OMputApp(dev)
-      OMputSymbol(dev, omOp.cd, omOp.name)
-      for arg in args repeat
-        OMwrite(dev, arg, false)
-      OMputEndApp(dev)
-    -- Most of the binary operators cannot be handled trivialy like the
-    -- unary ones since they have bound variables of one kind or another.
-    -- The special functions should be straightforward, but we don't have
-    -- a CD for them yet :-)
-    op = %defint  => outputOMDefint(dev, args)
-    op = integral => outputOMInt(dev, args)
-    op = %defsum  => outputOMDefsum(dev, args)
-    op = %defprod => outputOMDefprod(dev, args)
-    op = %power   => outputOMPower(dev, args)
-    op = binomial => outputOMBinomial(dev, args)
-    error concat ["No OpenMath definition for function ", string op]
- 
-  outputOMExpr(dev: OpenMathDevice, ex: Expression R): Void ==
-    ground? ex => OMwrite(dev, ground ex, false)
-    not((v := retractIfCan(ex)@Union(Symbol,"failed")) case "failed") =>
-      OMputVariable(dev, v)
-    not((w := isPlus ex) case "failed") => outputOMArith1(dev, "plus", w)
-    not((w := isTimes ex) case "failed") => outputOMArith1(dev, "times", w)
-    --not((y := isMult ex) case "failed") =>
-    --  outputOMArith("times", [OMwrite(y.coef)$Integer,
-    --          OMwrite(coerce y.var)])
-    -- At the time of writing we don't need both isExpt and isPower
-    -- here but they may be relevent when we integrate this stuff into
-    -- the main Expression code.  Note that if we don't check that
-    -- the exponent is non-trivial we get thrown into an infinite recursion.
---    not (((x := isExpt ex) case "failed") or one? x.exponent) =>
-    not (((x := isExpt ex) case "failed") or (x.exponent = 1)) =>
-      not((s := symbolIfCan(x.var)@Union(Symbol,"failed")) case "failed") =>
-        --outputOMPower(dev, [s::Expression(R), (x.exponent)::Expression(R)])
-        OMputApp(dev)
-        OMputSymbol(dev, "arith1", "power")
-        OMputVariable(dev, s)
-        OMputInteger(dev, x.exponent)
-        OMputEndApp(dev)
-      -- TODO: add error handling code here...
---    not (((z := isPower ex) case "failed") or one? z.exponent) =>
-    not (((z := isPower ex) case "failed") or (z.exponent = 1)) =>
-      outputOMPower(dev, [ z.val, z.exponent::Expression R ])
-      --OMputApp(dev)
-      --OMputSymbol(dev, "arith1", "power")
-      --outputOMExpr(dev, z.val)
-      --OMputInteger(dev, z.exponent)
-      --OMputEndApp(dev)
-    -- Must only be one top-level Kernel by this point
-    k : Kernel Expression R := first kernels ex
-    outputOMFunction(dev, name operator k, argument k)
-
-
-  ----------
-  -- Exports
-  ----------
-
-  OMwrite(ex: Expression R): String ==
-    s: String := ""
-    sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
-    dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
-    OMputObject(dev)
-    outputOMExpr(dev, ex)
-    OMputEndObject(dev)
-    OMclose(dev)
-    s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
-    s
-
-  OMwrite(ex: Expression R, wholeObj: Boolean): String ==
-    s: String := ""
-    sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
-    dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
-    if wholeObj then
-      OMputObject(dev)
-    outputOMExpr(dev, ex)
-    if wholeObj then
-      OMputEndObject(dev)
-    OMclose(dev)
-    s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
-    s
-
-  OMwrite(dev: OpenMathDevice, ex: Expression R): Void ==
-    OMputObject(dev)
-    outputOMExpr(dev, ex)
-    OMputEndObject(dev)
-
-  OMwrite(dev: OpenMathDevice, ex: Expression R, wholeObj: Boolean): Void ==
-    if wholeObj then
-      OMputObject(dev)
-    outputOMExpr(dev, ex)
-    if wholeObj then
-      OMputEndObject(dev)
-
-@
-\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 OMEXPR ExpressionToOpenMath>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/ore.spad.pamphlet b/src/algebra/ore.spad.pamphlet
deleted file mode 100644
index 8c5bc5c..0000000
--- a/src/algebra/ore.spad.pamphlet
+++ /dev/null
@@ -1,211 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra ore.spad}
-\author{Manuel Bronstein, Jean Della Dora, Stephen M. Watt}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package APPLYORE ApplyUnivariateSkewPolynomial}
-<<package APPLYORE ApplyUnivariateSkewPolynomial>>=
-)abbrev package APPLYORE ApplyUnivariateSkewPolynomial
-++ Author: Manuel Bronstein
-++ Date Created: 7 December 1993
-++ Date Last Updated: 1 February 1994
-++ Description:
-++   \spad{ApplyUnivariateSkewPolynomial} (internal) allows univariate
-++   skew polynomials to be applied to appropriate modules.
-ApplyUnivariateSkewPolynomial(R:Ring, M: LeftModule R,
-    P: UnivariateSkewPolynomialCategory R): with
-      apply: (P, M -> M, M) -> M
-        ++ apply(p, f, m) returns \spad{p(m)} where the action is given
-        ++ by \spad{x m = f(m)}.
-        ++ \spad{f} must be an R-pseudo linear map on M.
-   == add
-      apply(p, f, m) ==
-        w:M  := 0
-        mn:M := m
-        for i in 0..degree p repeat
-          w  := w + coefficient(p, i) * mn
-          mn := f mn
-        w
-
-@
-\section{package OREPCTO UnivariateSkewPolynomialCategoryOps}
-<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>=
-)abbrev package OREPCTO UnivariateSkewPolynomialCategoryOps
-++ Author: Manuel Bronstein
-++ Date Created: 1 February 1994
-++ Date Last Updated: 1 February 1994
-++ Description:
-++   \spad{UnivariateSkewPolynomialCategoryOps} provides products and
-++    divisions of univariate skew polynomials.
--- Putting those operations here rather than defaults in OREPCAT allows
--- OREPCAT to be defined independently of sigma and delta.
--- MB 2/94
-UnivariateSkewPolynomialCategoryOps(R, C): Exports == Implementation where
-    R: Ring
-    C: UnivariateSkewPolynomialCategory R
- 
-    N   ==> NonNegativeInteger
-    MOR ==> Automorphism R
-    QUOREM ==> Record(quotient: C, remainder: C)
- 
-    Exports ==> with
-        times: (C, C, MOR, R -> R) -> C
-           ++ times(p, q, sigma, delta) returns \spad{p * q}.
-           ++ \spad{\sigma} and \spad{\delta} are the maps to use.
-        apply: (C, R, R, MOR, R -> R) -> R
-          ++ apply(p, c, m, sigma, delta) returns \spad{p(m)} where the action
-          ++ is given by \spad{x m = c sigma(m) + delta(m)}.
-        if R has IntegralDomain then
-            monicLeftDivide: (C, C, MOR) -> QUOREM
-                ++ monicLeftDivide(a, b, sigma) returns the pair \spad{[q,r]}
-                ++ such that \spad{a = b*q + r} and the degree of \spad{r} is
-                ++ less than the degree of \spad{b}.
-                ++ \spad{b} must be monic.
-                ++ This process is called ``left division''.
-                ++ \spad{\sigma} is the morphism to use.
-            monicRightDivide: (C, C, MOR) -> QUOREM
-                ++ monicRightDivide(a, b, sigma) returns the pair \spad{[q,r]}
-                ++ such that \spad{a = q*b + r} and the degree of \spad{r} is
-                ++ less than the degree of \spad{b}.
-                ++ \spad{b} must be monic.
-                ++ This process is called ``right division''.
-                ++ \spad{\sigma} is the morphism to use.
-        if R has Field then
-            leftDivide: (C, C, MOR) -> QUOREM
-                ++ leftDivide(a, b, sigma) returns the pair \spad{[q,r]} such
-                ++ that \spad{a = b*q + r} and the degree of \spad{r} is
-                ++ less than the degree of \spad{b}.
-                ++ This process is called ``left division''.
-                ++ \spad{\sigma} is the morphism to use.
-            rightDivide: (C, C, MOR) -> QUOREM
-                ++ rightDivide(a, b, sigma) returns the pair \spad{[q,r]} such
-                ++ that \spad{a = q*b + r} and the degree of \spad{r} is
-                ++ less than the degree of \spad{b}.
-                ++ This process is called ``right division''.
-                ++ \spad{\sigma} is the morphism to use.
- 
-    Implementation ==> add
-        termPoly:         (R, N, C, MOR, R -> R) -> C
-        localLeftDivide : (C, C, MOR, R) -> QUOREM
-        localRightDivide: (C, C, MOR, R) -> QUOREM
- 
-        times(x, y, sigma, delta) ==
-          zero? y => 0
-          z:C := 0
-          while x ^= 0 repeat
-            z := z + termPoly(leadingCoefficient x, degree x, y, sigma, delta)
-            x := reductum x
-          z
- 
-        termPoly(a, n, y, sigma, delta) ==
-          zero? y => 0
-          (u := subtractIfCan(n, 1)) case "failed" => a * y
-          n1 := u::N
-          z:C := 0
-          while y ^= 0 repeat
-            m := degree y
-            b := leadingCoefficient y
-            z := z + termPoly(a, n1, monomial(sigma b, m + 1), sigma, delta)
-                   + termPoly(a, n1, monomial(delta b, m), sigma, delta)
-            y := reductum y
-          z
- 
-        apply(p, c, x, sigma, delta) ==
-          w:R  := 0
-          xn:R := x
-          for i in 0..degree p repeat
-            w  := w + coefficient(p, i) * xn
-            xn := c * sigma xn + delta xn
-          w
- 
-        -- localLeftDivide(a, b) returns [q, r] such that a = q b + r
-        -- b1 is the inverse of the leadingCoefficient of b
-        localLeftDivide(a, b, sigma, b1) ==
-            zero? b => error "leftDivide: division by 0"
-            zero? a or
-             (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
-                    [0,a]
-            q  := monomial((sigma**(-m))(b1 * leadingCoefficient a), n::N)
-            qr := localLeftDivide(a - b * q, b, sigma, b1)
-            [q + qr.quotient, qr.remainder]
- 
-        -- localRightDivide(a, b) returns [q, r] such that a = q b + r
-        -- b1 is the inverse of the leadingCoefficient of b
-        localRightDivide(a, b, sigma, b1) ==
-            zero? b => error "rightDivide: division by 0"
-            zero? a or
-              (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
-                    [0,a]
-            q := monomial(leadingCoefficient(a) * (sigma**n) b1, n::N)
-            qr := localRightDivide(a - q * b, b, sigma, b1)
-            [q + qr.quotient, qr.remainder]
- 
-        if R has IntegralDomain then
-            monicLeftDivide(a, b, sigma) ==
-                unit?(u := leadingCoefficient b) =>
-                    localLeftDivide(a, b, sigma, recip(u)::R)
-                error "monicLeftDivide: divisor is not monic"
- 
-            monicRightDivide(a, b, sigma) ==
-                unit?(u := leadingCoefficient b) =>
-                    localRightDivide(a, b, sigma, recip(u)::R)
-                error "monicRightDivide: divisor is not monic"
- 
-        if R has Field then
-            leftDivide(a, b, sigma) ==
-                localLeftDivide(a, b, sigma, inv leadingCoefficient b)
- 
-            rightDivide(a, b, sigma) ==
-                localRightDivide(a, b, sigma, inv leadingCoefficient b)
-
-@
-\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 APPLYORE ApplyUnivariateSkewPolynomial>>
-<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/out.spad.pamphlet b/src/algebra/out.spad.pamphlet
deleted file mode 100644
index 19388b7..0000000
--- a/src/algebra/out.spad.pamphlet
+++ /dev/null
@@ -1,311 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra out.spad}
-\author{Stephen M. Watt, Robert S. Sutor}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package OUT OutputPackage}
-<<package OUT OutputPackage>>=
-)abbrev package OUT OutputPackage
-++ Author: Stephen M. Watt
-++ Date Created: February 1986
-++ Date Last Updated: October 27 1995 (MCD)
-++ Basic Operations: output
-++ Related Constructors: OutputForm
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: OutPackage allows pretty-printing from programs.
-
-OutputPackage: with
-        output: String -> Void
-            ++ output(s) displays the string s on the ``algebra output''
-            ++ stream, as defined by \spadsyscom{set output algebra}.
-        output: OutputForm -> Void
-            ++ output(x) displays the output form x on the
-            ++ ``algebra output'' stream, as defined by
-            ++ \spadsyscom{set output algebra}.
-        output: (String, OutputForm) -> Void
-            ++ output(s,x) displays the string s followed by the form x
-            ++ on the ``algebra output'' stream, as defined by
-            ++ \spadsyscom{set output algebra}.
-        outputList: (List Any) -> Void
-            ++ outputList(l) displays the concatenated components of the
-            ++ list l on the ``algebra output'' stream, as defined by
-            ++ \spadsyscom{set output algebra}; quotes are stripped
-	    ++ from strings.
-
-    == add
-        --ExpressionPackage()
-        E      ==> OutputForm
-        putout ==> mathprint$Lisp
-
-        s: String
-        e: OutputForm
-        l: List Any
-
-        output e ==
-            mathprint(e)$Lisp
-            void()
-        output s ==
-            output(s:E)
-        output(s,e) ==
-            output blankSeparate [s:E, e]
-        outputList(l) ==                                -- MGR
-	  output hconcat
-	    [if retractable?(x)$AnyFunctions1(String) then
-                message(retract(x)$AnyFunctions1(String))$OutputForm
-              else
-                x::OutputForm
-             for x in l]
-
-@
-\section{package SPECOUT SpecialOutputPackage}
-<<package SPECOUT SpecialOutputPackage>>=
-)abbrev package SPECOUT SpecialOutputPackage
-++ Author: Stephen M. Watt
-++ Date Created: September 1986
-++ Date Last Updated: May 23, 1991
-++ Basic Operations: outputAsFortran, outputAsScript, outputAsTex
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: SpecialOutputPackage allows FORTRAN, Tex and
-++   Script Formula Formatter output from programs.
-
-SpecialOutputPackage: public == private where
-  public == with
-    outputAsFortran: (String,OutputForm) -> Void
-      ++ outputAsFortran(v,o) sends output v = o in FORTRAN format
-      ++ to the destination defined by \spadsyscom{set output fortran}.
-    outputAsFortran: OutputForm          -> Void
-      ++ outputAsFortran(o) sends output o in FORTRAN format.
-    outputAsScript:  OutputForm          -> Void
-      ++ outputAsScript(o) sends output o in Script Formula Formatter format
-      ++ to the destination defined by \spadsyscom{set output formula}.
-    outputAsTex:     OutputForm          -> Void
-      ++ outputAsTex(o) sends output o in Tex format to the destination
-      ++ defined by \spadsyscom{set output tex}.
-    outputAsFortran: List OutputForm     -> Void
-      ++ outputAsFortran(l) sends (for each expression in the list l)
-      ++ output in FORTRAN format to the destination defined by
-      ++ \spadsyscom{set output fortran}.
-    outputAsScript:  List OutputForm     -> Void
-      ++ outputAsScript(l) sends (for each expression in the list l)
-      ++ output in Script Formula Formatter format to the destination defined.
-      ++ by \spadsyscom{set output forumula}.
-    outputAsTex:     List OutputForm     -> Void
-      ++ outputAsTex(l) sends (for each expression in the list l)
-      ++ output in Tex format to the destination as defined by
-      ++ \spadsyscom{set output tex}.
-
-  private == add
-    e : OutputForm
-    l : List OutputForm
-    var : String
-    --ExpressionPackage()
-
-    juxtaposeTerms: List OutputForm -> OutputForm
-    juxtaposeTerms l == blankSeparate l
-
-    outputAsFortran e ==
-      dispfortexp$Lisp e
-      void()$Void
-
-    outputAsFortran(var,e) ==
-      e := var::Symbol::OutputForm  = e
-      dispfortexp(e)$Lisp
-      void()$Void
-
-    outputAsFortran l ==
-      dispfortexp$Lisp juxtaposeTerms l
-      void()$Void
-
-    outputAsScript e ==
-      formulaFormat$Lisp e
-      void()$Void
-
-    outputAsScript l ==
-      formulaFormat$Lisp juxtaposeTerms l
-      void()$Void
-
-    outputAsTex e ==
-      texFormat$Lisp e
-      void()$Void
-
-    outputAsTex l ==
-      texFormat$Lisp juxtaposeTerms l
-      void()$Void
-
-@
-\section{package DISPLAY DisplayPackage}
-<<package DISPLAY DisplayPackage>>=
-)abbrev package DISPLAY DisplayPackage
-++ Author: Robert S. Sutor
-++ Date Created: September 1986
-++ Date Last Updated:
-++ Basic Operations: bright, newLine, copies, center, say, sayLength
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: DisplayPackage allows one to print strings in a nice manner,
-++ including highlighting substrings.
-
-DisplayPackage: public == private where
-  I       ==> Integer
-  L       ==> List
-  S       ==> String
-  RECLR   ==> Record(lhs : S, rhs : S)
-
-  public  == with
-    bright:       S           -> L S
-      ++ bright(s) sets the font property of the string s to bold-face type.
-    bright:       L S         -> L S
-      ++ bright(l) sets the font property of a list of strings, l, to
-      ++ bold-face type.
-    newLine:      ()          -> S
-      ++ newLine() sends a new line command to output.
-
-    copies:       (I,S)       -> S
-      ++ copies(i,s) will take a string s and create a new string composed of
-      ++ i copies of s.
-    center:       (S,I,S)     -> S
-      ++ center(s,i,s) takes the first string s, and centers it within a string
-      ++ of length i, in which the other elements of the string are composed
-      ++ of as many replications as possible of the second indicated string, s
-      ++ which must have a length greater than that of an empty string.
-    center:       (L S,I,S)   -> L S
-      ++ center(l,i,s) takes a list of strings l, and centers them within a
-      ++ list of strings which is i characters long, in which the remaining
-      ++ spaces are filled with strings composed of as many repetitions as
-      ++ possible of the last string parameter s.
-
-    say:          S           -> Void
-      ++ say(s) sends a string s to output.
-    say:          L S         -> Void
-      ++ say(l) sends a list of strings l to output.
-    sayLength:    S           -> I
-      ++ sayLength(s) returns the length of a string s as an integer.
-    sayLength:    L S         -> I
-      ++ sayLength(l) returns the length of a list of strings l as an integer.
-
-  private == add
-    --StringManipulations()
-
-    center0:  (I,I,S) -> RECLR
-
-    s : S
-    l : L S
-
-    HION    : S := "%b"
-    HIOFF   : S := "%d"
-    NEWLINE : S := "%l"
-
-    bright s == [HION,s,HIOFF]$(L S)
-    bright l == cons(HION,append(l,list HIOFF))
-    newLine() == NEWLINE
-
-    copies(n : I, s : S) ==
-      n < 1 => ""
-      n = 1 => s
-      t : S := copies(n quo 2, s)
-      odd? n => concat [s,t,t]
-      concat [t,t]
-
-    center0(len : I, wid : I, fill : S) : RECLR ==
-      (wid < 1) or (len >= wid) => ["",""]$RECLR
-      m : I := (wid - len) quo 2
-      t : S := copies(1 + (m quo (sayLength fill)),fill)
-      [t(1..m),t(1..wid-len-m)]$RECLR
-
-    center(s, wid, fill) ==
-      wid < 1 => ""
-      len : I := sayLength s
-      len = wid => s
-      len > wid => s(1..wid)
-      rec : RECLR := center0(len,wid,fill)
-      concat [rec.lhs,s,rec.rhs]
-
-    center(l, wid, fill) ==
-      wid < 1 => [""]$(L S)
-      len : I := sayLength l
-      len = wid => l
---    len > wid => s(1..wid)
-      rec : RECLR := center0(len,wid,fill)
-      cons(rec.lhs,append(l,list rec.rhs))
-
-    say s ==
-      sayBrightly$Lisp s
-      void()$Void
-
-    say l ==
-      sayBrightly$Lisp l
-      void()$Void
-
-    sayLength s == #s
-
-    sayLength l ==
-      sum : I := 0
-      for s in l repeat
-        s = HION      => sum := sum + 1
-        s = HIOFF     => sum := sum + 1
-        s = NEWLINE   => sum
-        sum := sum + sayLength s
-      sum
-
-@
-\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 OUT OutputPackage>>
-<<package SPECOUT SpecialOutputPackage>>
-<<package DISPLAY DisplayPackage>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/outform.spad.pamphlet b/src/algebra/outform.spad.pamphlet
deleted file mode 100644
index efea968..0000000
--- a/src/algebra/outform.spad.pamphlet
+++ /dev/null
@@ -1,247 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra outform.spad}
-\author{Stephen M. Watt}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{package NUMFMT NumberFormats}
-<<package NUMFMT NumberFormats>>=
-)abbrev package NUMFMT NumberFormats
-++ SMW March 88
-++ Keywords: string manipulation, roman numerals, format
-++ Description:
-++ NumberFormats provides function to format and read arabic and
-++ roman numbers, to convert numbers to strings and to read
-++ floating-point numbers.
-
-NumberFormats(): NFexports == NFimplementation where
-    PI ==> PositiveInteger
-    I  ==> Integer
-    C  ==> Character
-    F  ==> Float
-    S  ==> String
-    V  ==> PrimitiveArray
-
-    NFexports ==> with
-        FormatArabic: PI -> S
-            ++ FormatArabic(n) forms an Arabic numeral
-            ++ string from an integer n.
-        ScanArabic:   S -> PI
-            ++ ScanArabic(s) forms an integer from an Arabic numeral string s.
-        FormatRoman:  PI -> S
-            ++ FormatRoman(n) forms a Roman numeral string from an integer n.
-        ScanRoman:    S -> PI
-            ++ ScanRoman(s) forms an integer from a Roman numeral string s.
-        ScanFloatIgnoreSpaces: S -> F
-            ++ ScanFloatIgnoreSpaces(s) forms a floating point number from
-            ++ the string s ignoring any spaces. Error is generated if the
-            ++ string is not recognised as a floating point number.
-        ScanFloatIgnoreSpacesIfCan: S -> Union(F, "failed")
-            ++ ScanFloatIgnoreSpacesIfCan(s) tries to form a floating point number from
-            ++ the string s ignoring any spaces.
-
-
-    NFimplementation ==> add
-        import SExpression
-        import Symbol
-        replaceD: C -> C
-        replaced: C -> C
-        contract: S -> S
-        check: S ->Boolean
-        replaceD c ==
-          if c = char "D" then char "E" else c
-        replaced c ==
-          if c = char "d" then char "E" else c
-        contract s ==
-          s:= map(replaceD,s)
-          s:= map(replaced,s)
-          ls:List S := split(s,char " ")$String
-          s:= concat ls
-        check s ==
-          NUMBERP(READ_-FROM_-STRING(s)$Lisp)$Lisp and
-           -- if there is an "E" then there must be a "."
-           -- this is not caught by code above
-           -- also if the exponent is v.big the above returns false
-           not (any?(#1=char "E",s) and not any?(#1=char ".",s) )
-
---        Original interpreter function:
---        )lis (defun scanstr(x) (spadcomp::|parseFromString| x))
-        sexfloat:SExpression:=convert(coerce("Float")@Symbol)$SExpression
-        ScanFloatIgnoreSpaces s ==
-          s := contract s
-          not check s => error "Non-numeric value"
-          sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
-          sCheck := car(car(sex))
-          if (sCheck=sexfloat) = true then
-             f := (cdr cdr sex) pretend Float
-          else
-             if integer?(cdr sex) = true then
-                f := (cdr sex) pretend Integer
-                f::F
-             else
-                error "Non-numeric value"
-
-        ScanFloatIgnoreSpacesIfCan s ==
-          s := contract s
-	  not check s => "failed"
-          sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
-          sCheck := car(car(sex))
-          if (sCheck=sexfloat) = true then
-             f := (cdr cdr sex) pretend Float
-          else
-             if integer?(cdr sex) = true then
-                f := (cdr sex) pretend Integer
-                f::F
-             else
-                "failed"
-
-        units:V S :=
-           construct ["","I","II","III","IV","V","VI","VII","VIII","IX"]
-        tens :V S :=
-           construct ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"]
-        hunds:V S :=
-           construct ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]
-        umin := minIndex units
-        tmin := minIndex tens
-        hmin := minIndex hunds
-        romval:V I := new(256, -1)
-        romval ord char(" ")$C := 0
-        romval ord char("I")$C := 1
-        romval ord char("V")$C := 5
-        romval ord char("X")$C := 10
-        romval ord char("L")$C := 50
-        romval ord char("C")$C := 100
-        romval ord char("D")$C := 500
-        romval ord char("M")$C := 1000
-        thou:C  := char "M"
-        plen:C  := char "("
-        pren:C  := char ")"
-        ichar:C := char "I"
-
-        FormatArabic n == STRINGIMAGE(n)$Lisp
-        ScanArabic   s == PARSE_-INTEGER(s)$Lisp
-
-        FormatRoman pn ==
-            n := pn::Integer
-            -- Units
-            d := (n rem 10) + umin
-            n := n quo 10
-            s := units.d
-            zero? n => s
-            -- Tens
-            d := (n rem 10) + tmin
-            n := n quo 10
-            s := concat(tens.d, s)
-            zero? n => s
-            -- Hundreds
-            d := (n rem 10) + hmin
-            n := n quo 10
-            s := concat(hunds.d, s)
-            zero? n => s
-            -- Thousands
-            d := n rem 10
-            n := n quo 10
-            s := concat(new(d::NonNegativeInteger, thou), s)
-            zero? n => s
-            -- Ten thousand and higher
-            for i in 2.. while not zero? n repeat
-                -- Coefficient of 10**(i+2)
-                d := n rem 10
-                n := n quo 10
-                zero? d => "iterate"
-                m0:String := concat(new(i,plen),concat("I",new(i,pren)))
-                mm := concat([m0 for j in 1..d]$List(String))
-                -- strictly speaking the blank is gratuitous
-                if #s > 0 then s := concat(" ", s)
-                s  := concat(mm, s)
-            s
-
-        -- ScanRoman
-        --
-        -- The Algorithm:
-        --    Read number from right to left.  When the current
-        --    numeral is lower in magnitude than the previous maximum
-        --    then subtract otherwise add.
-        --    Shift left and repeat until done.
-
-        ScanRoman s ==
-            s      := upperCase s
-            tot: I := 0
-            Max: I := 0
-            i:   I := maxIndex s
-            while i >= minIndex s repeat
-                -- Read a single roman digit
-                c := s.i; i := i-1
-                n := romval ord c
-                -- (I)=1000, ((I))=10000, (((I)))=100000, etc
-                if n < 0 then
-                    c ^= pren =>
-                       error ["Improper character in Roman numeral: ",c]
-                    nprens: PI := 1
-                    while c = pren and i >= minIndex s repeat
-                       c := s.i; i := i-1
-                       if c = pren then nprens := nprens+1
-                    c ^= ichar =>
-                       error "Improper Roman numeral: (x)"
-                    for k in 1..nprens while i >= minIndex s repeat
-                       c := s.i; i := i-1
-                       c ^= plen =>
-                          error "Improper Roman numeral: unbalanced ')'"
-                    n := 10**(nprens + 2)
-                if n < Max then
-                    tot := tot - n
-                else
-                    tot := tot + n
-                    Max := n
-            tot < 0 => error ["Improper Roman numeral: ", tot]
-            tot::PI
-
-@
-\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 NUMFMT NumberFormats>>
-@
-\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 9b921de..1b1365b 100644
--- a/src/axiom-website/patches.html
+++ b/src/axiom-website/patches.html
@@ -927,5 +927,7 @@ bookvol10.4 add packages<br/>
 bookvol10.4 add packages<br/>
 <a href="patches/20090207.01.tpd.patch">20090207.01.tpd.patch</a>
 bookvol10.4 add packages<br/>
+<a href="patches/20090207.02.tpd.patch">20090207.02.tpd.patch</a>
+bookvol10.4 add packages<br/>
  </body>
 </html>
