diff --git a/books/bookvol10.2.pamphlet b/books/bookvol10.2.pamphlet
index 5c69035..bb73b77 100644
--- a/books/bookvol10.2.pamphlet
+++ b/books/bookvol10.2.pamphlet
@@ -304,6 +304,7 @@ This is the root of the category hierarchy and is not represented by code.
 \pageto{InnerEvalable}{IEVALAB}
 \pageto{Logic}{LOGIC}
 \pageto{OpenMath}{OM}
+\pageto{PartialTranscendentalFunctions}{PTRANFN}
 \pageto{Patternable}{PATAB}
 \pageto{PrimitiveFunctionCategory}{PRIMCAT}
 \pageto{RadicalCategory}{RADCAT}
@@ -552,7 +553,8 @@ For example, a domain of mathematical objects which has the
 equal if and only if their data structures are equal.
 \item {\bf \cross{ATTREG}{approximate}} means ``is an approximation to
 the real numbers''.
-n\end{itemize}
+\item {\bf \cross{ATTREG}{complex}} means that this domain has $\sqrt{-1}$
+\end{itemize}
 
 <<category ATTREG AttributeRegistry>>=
 )abbrev category ATTREG AttributeRegistry
@@ -1060,6 +1062,7 @@ digraph pic {
 
 {\bf See:}\\
 \pageto{EltableAggregate}{ELTAGG}
+\pageto{LinearOrdinaryDifferentialOperatorCategory}{LODOCAT}
 \pageto{UnivariatePolynomialCategory}{UPOLYC}
 \pagefrom{Category}{CATEGORY}
 
@@ -1128,17 +1131,10 @@ digraph pic {
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"UnivariatePolynomialCategory(a:Ring)" [color=lightblue];
-"UnivariatePolynomialCategory(a:Ring)" -> "POLYCAT..."
-"UnivariatePolynomialCategory(a:Ring)" -> "ELTAB..."
-"UnivariatePolynomialCategory(a:Ring)" -> "DIFRING..."
-"UnivariatePolynomialCategory(a:Ring)" -> "DIFEXT..."
-
-"POLYCAT..." [color=lightblue];
-"ELTAB..." [color=lightblue];
-"DIFRING..." [color=lightblue];
-"DIFEXT..." [color=lightblue];
+"Eltable(a:SetCategory,b:Type)" [color=lightblue];
+"Eltable(a:SetCategory,b:Type)" -> "Category"
 
+"Category" [color=lightblue];
 }
 
 @
@@ -1413,10 +1409,200 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{PartialTranscendentalFunctions}{PTRANFN}
+\pagepic{ps/v102partialtranscendentalfunctions.ps}{PTRANFN}{1.00}
+
+{\bf See:}\\
+\pagefrom{Category}{CATEGORY}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{PTRANFN}{acosIfCan} &
+\cross{PTRANFN}{acoshIfCan} &
+\cross{PTRANFN}{acotIfCan} &
+\cross{PTRANFN}{acothIfCan} &
+\cross{PTRANFN}{acscIfCan} \\
+\cross{PTRANFN}{acschIfCan} &
+\cross{PTRANFN}{asecIfCan} &
+\cross{PTRANFN}{asechIfCan} &
+\cross{PTRANFN}{asinIfCan} &
+\cross{PTRANFN}{asinhIfCan} \\
+\cross{PTRANFN}{atanIfCan} &
+\cross{PTRANFN}{atanhIfCan} &
+\cross{PTRANFN}{cosIfCan} &
+\cross{PTRANFN}{coshIfCan} &
+\cross{PTRANFN}{cotIfCan} \\
+\cross{PTRANFN}{cothIfCan} &
+\cross{PTRANFN}{cscIfCan} &
+\cross{PTRANFN}{cschIfCan} &
+\cross{PTRANFN}{expIfCan} &
+\cross{PTRANFN}{logIfCan} \\
+\cross{PTRANFN}{nthRootIfCan} &
+\cross{PTRANFN}{secIfCan} &
+\cross{PTRANFN}{sechIfCan} &
+\cross{PTRANFN}{sinIfCan} &
+\cross{PTRANFN}{sinhIfCan} \\
+\cross{PTRANFN}{tanIfCan} &
+\cross{PTRANFN}{tanhIfCan} &&&
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ acosIfCan : K -> Union(K,"failed")   
+ acoshIfCan : K -> Union(K,"failed")
+ acotIfCan : K -> Union(K,"failed")
+ acothIfCan : K -> Union(K,"failed")
+ acscIfCan : K -> Union(K,"failed")   
+ acschIfCan : K -> Union(K,"failed")
+ asecIfCan : K -> Union(K,"failed")
+ asechIfCan : K -> Union(K,"failed")
+ asinIfCan : K -> Union(K,"failed")   
+ asinhIfCan : K -> Union(K,"failed")
+ atanIfCan : K -> Union(K,"failed")
+ atanhIfCan : K -> Union(K,"failed")
+ cosIfCan : K -> Union(K,"failed")    
+ coshIfCan : K -> Union(K,"failed")
+ cotIfCan : K -> Union(K,"failed")    
+ cothIfCan : K -> Union(K,"failed")
+ cscIfCan : K -> Union(K,"failed")    
+ cschIfCan : K -> Union(K,"failed")
+ expIfCan : K -> Union(K,"failed")    
+ logIfCan : K -> Union(K,"failed")
+ nthRootIfCan : (K,NonNegativeInteger) -> Union(K,"failed")
+ secIfCan : K -> Union(K,"failed")    
+ sechIfCan : K -> Union(K,"failed")
+ sinIfCan : K -> Union(K,"failed")    
+ sinhIfCan : K -> Union(K,"failed")
+ tanIfCan : K -> Union(K,"failed")    
+ tanhIfCan : K -> Union(K,"failed")
+\end{verbatim}
+
+<<category PTRANFN PartialTranscendentalFunctions>>=
+)abbrev category PTRANFN PartialTranscendentalFunctions
+++ Description of a package which provides partial transcendental
+++ functions, i.e. functions which return an answer or "failed"
+++ Author: Clifton J. Williamson
+++ Date Created: 12 February 1990
+++ Date Last Updated: 14 February 1990
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This is the description of any package which provides partial
+++ functions on a domain belonging to TranscendentalFunctionCategory.
+ 
+PartialTranscendentalFunctions(K): Category == Definition where
+  K :     TranscendentalFunctionCategory
+  NNI ==> NonNegativeInteger
+ 
+  Definition ==> with
+ 
+--% Exponentials and Logarithms
+ 
+    nthRootIfCan: (K,NNI) -> Union(K,"failed")
+      ++ nthRootIfCan(z,n) returns the nth root of z if possible,
+      ++ and "failed" otherwise.
+    expIfCan: K -> Union(K,"failed")
+      ++ expIfCan(z) returns exp(z) if possible, and "failed" otherwise.
+    logIfCan: K -> Union(K,"failed")
+      ++ logIfCan(z) returns log(z) if possible, and "failed" otherwise.
+ 
+--% TrigonometricFunctionCategory
+ 
+    sinIfCan : K -> Union(K,"failed")
+      ++ sinIfCan(z) returns sin(z) if possible, and "failed" otherwise.
+    cosIfCan: K -> Union(K,"failed")
+      ++ cosIfCan(z) returns cos(z) if possible, and "failed" otherwise.
+    tanIfCan: K -> Union(K,"failed")
+      ++ tanIfCan(z) returns tan(z) if possible, and "failed" otherwise.
+    cotIfCan: K -> Union(K,"failed")
+      ++ cotIfCan(z) returns cot(z) if possible, and "failed" otherwise.
+    secIfCan: K -> Union(K,"failed")
+      ++ secIfCan(z) returns sec(z) if possible, and "failed" otherwise.
+    cscIfCan: K -> Union(K,"failed")
+      ++ cscIfCan(z) returns csc(z) if possible, and "failed" otherwise.
+ 
+--% ArcTrigonometricFunctionCategory
+ 
+    asinIfCan: K -> Union(K,"failed")
+      ++ asinIfCan(z) returns asin(z) if possible, and "failed" otherwise.
+    acosIfCan: K -> Union(K,"failed")
+      ++ acosIfCan(z) returns acos(z) if possible, and "failed" otherwise.
+    atanIfCan: K -> Union(K,"failed")
+      ++ atanIfCan(z) returns atan(z) if possible, and "failed" otherwise.
+    acotIfCan: K -> Union(K,"failed")
+      ++ acotIfCan(z) returns acot(z) if possible, and "failed" otherwise.
+    asecIfCan: K -> Union(K,"failed")
+      ++ asecIfCan(z) returns asec(z) if possible, and "failed" otherwise.
+    acscIfCan: K -> Union(K,"failed")
+      ++ acscIfCan(z) returns acsc(z) if possible, and "failed" otherwise.
+ 
+--% HyperbolicFunctionCategory
+ 
+    sinhIfCan: K -> Union(K,"failed")
+      ++ sinhIfCan(z) returns sinh(z) if possible, and "failed" otherwise.
+    coshIfCan: K -> Union(K,"failed")
+      ++ coshIfCan(z) returns cosh(z) if possible, and "failed" otherwise.
+    tanhIfCan: K -> Union(K,"failed")
+      ++ tanhIfCan(z) returns tanh(z) if possible, and "failed" otherwise.
+    cothIfCan: K -> Union(K,"failed")
+      ++ cothIfCan(z) returns coth(z) if possible, and "failed" otherwise.
+    sechIfCan: K -> Union(K,"failed")
+      ++ sechIfCan(z) returns sech(z) if possible, and "failed" otherwise.
+    cschIfCan: K -> Union(K,"failed")
+      ++ cschIfCan(z) returns csch(z) if possible, and "failed" otherwise.
+ 
+--% ArcHyperbolicFunctionCategory
+ 
+    asinhIfCan: K -> Union(K,"failed")
+      ++ asinhIfCan(z) returns asinh(z) if possible, and "failed" otherwise.
+    acoshIfCan: K -> Union(K,"failed")
+      ++ acoshIfCan(z) returns acosh(z) if possible, and "failed" otherwise.
+    atanhIfCan: K -> Union(K,"failed")
+      ++ atanhIfCan(z) returns atanh(z) if possible, and "failed" otherwise.
+    acothIfCan: K -> Union(K,"failed")
+      ++ acothIfCan(z) returns acoth(z) if possible, and "failed" otherwise.
+    asechIfCan: K -> Union(K,"failed")
+      ++ asechIfCan(z) returns asech(z) if possible, and "failed" otherwise.
+    acschIfCan: K -> Union(K,"failed")
+      ++ acschIfCan(z) returns acsch(z) if possible, and "failed" otherwise.
+
+@
+<<PTRANFN.dotabb>>=
+"PTRANFN"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PTRANFN"];
+"PTRANFN" -> "CATEGORY"
+
+@
+<<PTRANFN.dotfull>>=
+"PartialTranscendentalFunctions(TranscendentalFunctionCategory)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PTRANFN"];
+"PartialTranscendentalFunctions(TranscendentalFunctionCategory)" ->
+   "Category()"
+
+@
+<<PTRANFN.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"PartialTranscendentalFunctions(TranscendentalFunctionCategory)"
+ [color=lightblue];
+"PartialTranscendentalFunctions(TranscendentalFunctionCategory)" ->
+   "Category"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{Patternable}{PATAB}
 \pagepic{ps/v102patternable.ps}{PATAB}{1.00}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{FunctionSpace}{FS}
 \pageto{IntegerNumberSystem}{INS}
 \pageto{QuotientFieldCategory}{QFCAT}
@@ -1474,6 +1660,10 @@ Patternable(R:Type): Category == with
  [color=seagreen,href="bookvol10.2.pdf#nameddest=PATAB"];
 "Patternable(OrderedSet)" -> "Patternable(a:Type)"
 
+"Patternable(CommutativeRing)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=PATAB"];
+"Patternable(CommutativeRing)" -> "Patternable(a:Type)"
+
 @
 <<PATAB.dotpic>>=
 digraph pic {
@@ -1523,7 +1713,7 @@ PrimitiveFunctionCategory(): Category == with
 
 @
 <<PRIMCAT.dotabb>>=
-"PRIMCAT" -> "CATEGORY"
+"PRIMCAT"
  [color=lightblue,href="bookvol10.2.pdf#nameddest=PRIMCAT"];
 "PRIMCAT" -> "CATEGORY"
 
@@ -1554,6 +1744,7 @@ digraph pic {
 {\bf See:}\\
 \pageto{AlgebraicallyClosedField}{ACF}
 \pageto{IntervalCategory}{INTCAT}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{RealNumberSystem}{RNS}
 \pageto{UnivariateLaurentSeriesCategory}{ULSCAT}
 \pageto{UnivariatePuiseuxSeriesCategory}{UPXSCAT}
@@ -1647,6 +1838,7 @@ digraph pic {
 \pageto{QuotientFieldCategory}{QFCAT}
 \pageto{RealNumberSystem}{RNS}
 \pageto{UnivariateLaurentSeriesConstructorCategory}{ULSCCAT}
+\pageto{UnivariatePuiseuxSeriesConstructorCategory}{UPXSCCA}
 \pageto{XFreeAlgebra}{XFALG}
 \pagefrom{Category}{CATEGORY}
 
@@ -1740,6 +1932,11 @@ RetractableTo(S: Type): Category == with
  [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
 "RetractableTo(CommutativeRing)" -> "RetractableTo(a:Type)"
 
+"RetractableTo(UnivariatePuiseuxSeriesCategory(Ring))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
+"RetractableTo(UnivariatePuiseuxSeriesCategory(Ring))"
+  -> "RetractableTo(a:Type)"
+
 "RetractableTo(Field)"
  [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
 "RetractableTo(Field)" -> "RetractableTo(a:Type)"
@@ -2535,12 +2732,16 @@ digraph pic {
 \pagepic{ps/v102fullyretractableto.ps}{FRETRCT}{1.00}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{DirectProductCategory}{DIRPCAT}
 \pageto{FiniteAbelianMonoidRing}{FAMR}
 \pageto{FunctionSpace}{FS}
 \pageto{MonogenicAlgebra}{MONOGEN}
 \pageto{OctonionCategory}{OC}
+\pageto{QuaternionCategory}{QUATCAT}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{SquareMatrixCategory}{SMATCAT}
+\pageto{UnivariateSkewPolynomialCategory}{OREPCAT}
 \pagefrom{RetractableTo}{RETRACT}
 
 {\bf Exports:}\\
@@ -2631,6 +2832,10 @@ FullyRetractableTo(S: Type): Category == RetractableTo(S) with
  [color=seagreen,href="bookvol10.2.pdf#nameddest=FRETRCT"];
 "FullyRetractableTo(a:SetCategory)" -> "FullyRetractableTo(a:Type)"
 
+"FullyRetractableTo(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=FRETRCT"];
+"FullyRetractableTo(Fraction(Integer))" -> "FullyRetractableTo(a:Type)"
+
 @
 <<FRETRCT.dotpic>>=
 digraph pic {
@@ -2653,6 +2858,7 @@ digraph pic {
 \pagepic{ps/v102fullypatternmatchable.ps}{FPATMAB}{1.00}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{FunctionSpace}{FS}
 \pageto{QuotientFieldCategory}{QFCAT}
 \pagefrom{Type}{TYPE}
@@ -2742,6 +2948,11 @@ FullyPatternMatchable(R:Type): Category == Type with
 "FullyPatternMatchable(OrderedSet)" ->
   "FullyPatternMatchable(a:Type)"
 
+"FullyPatternMatchable(CommutativeRing)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=FPATMAB"];
+"FullyPatternMatchable(CommutativeRing)" ->
+  "FullyPatternMatchable(a:Type)"
+
 @
 <<FPATMAB.dotpic>>=
 digraph pic {
@@ -3249,6 +3460,7 @@ digraph pic {
 \pageto{PartialDifferentialEquationsSolverCategory}{PDECAT}
 \pageto{PatternMatchable}{PATMAB}
 \pageto{PolynomialSetCategory}{PSETCAT}
+\pageto{RealRootCharacterizationCategory}{RRCC}
 \pageto{SemiGroup}{SGROUP}
 \pageto{SetAggregate}{SETAGG}
 \pageto{SExpressionCategory}{SEXCAT}
@@ -3488,7 +3700,7 @@ TranscendentalFunctionCategory(): Category ==
 
 @
 <<TRANFUN.dotabb>>=
-"TRANFUN" -> "TRIGCAT"
+"TRANFUN"
  [color=lightblue,href="bookvol10.2.pdf#nameddest=TRANFUN"];
 "TRANFUN" -> "TRIGCAT"
 "TRANFUN" -> "ATRIG"
@@ -4296,7 +4508,9 @@ digraph pic {
 \pagepic{ps/v102fullyevalableover.ps}{FEVALAB}{0.75}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{OctonionCategory}{OC}
+\pageto{QuaternionCategory}{QUATCAT}
 \pageto{QuotientFieldCategory}{QFCAT}
 \pagefrom{Category}{CATEGORY}
 
@@ -4370,6 +4584,7 @@ FullyEvalableOver(R:SetCategory): Category == with
 "FEVALAB" -> "EVALAB"
 "FEVALAB" -> "IEVALAB"
 "FEVALAB" -> "CATEGORY"
+
 @
 <<FEVALAB.dotfull>>=
 "FullyEvalableOver(a:SetCategory)"
@@ -6460,6 +6675,189 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{RealRootCharacterizationCategory}{RRCC}
+\pagepic{ps/v102realrootcharacterizationcategory.ps}{RRCC}{0.60}
+
+{\bf See:}\\
+\pagefrom{SetCategory}{SETCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{RRCC}{allRootsOf} &
+\cross{RRCC}{approximate} &
+\cross{RRCC}{coerce} &
+\cross{RRCC}{definingPolynomial} \\
+\cross{RRCC}{hash} &
+\cross{RRCC}{latex} &
+\cross{RRCC}{negative?} &
+\cross{RRCC}{positive?} \\
+\cross{RRCC}{recip} &
+\cross{RRCC}{relativeApprox} &
+\cross{RRCC}{rootOf} &
+\cross{RRCC}{sign} \\
+\cross{RRCC}{zero?} &
+\cross{RRCC}{?=?} &
+\cross{RRCC}{?~=?} &
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ approximate : (ThePols,%,TheField) -> TheField
+ allRootsOf : ThePols -> List %
+ definingPolynomial : % -> ThePols
+ relativeApprox : (ThePols,%,TheField) -> TheField
+ sign : (ThePols,%) -> Integer        
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ negative? : (ThePols,%) -> Boolean
+ positive? : (ThePols,%) -> Boolean
+ recip : (ThePols,%) -> Union(ThePols,"failed")
+ rootOf : (ThePols,PositiveInteger) -> Union(%,"failed")
+ zero? : (ThePols,%) -> Boolean
+\end{verbatim}
+
+These exports come from \refto{SetCategory}():
+\begin{verbatim}
+ coerce : % -> OutputForm             
+ hash : % -> SingleInteger            
+ latex : % -> String
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+\end{verbatim}
+
+<<category RRCC RealRootCharacterizationCategory>>=
+)abbrev category RRCC RealRootCharacterizationCategory
+++ Author: Renaud Rioboo
+++ Date Created: summer 1992
+++ Date Last Updated: January 2004
+++ Basic Functions: provides operations with generic real roots of 
+++                  polynomials 
+++ Related Constructors: RealClosure, RightOpenIntervalRootCharacterization
+++ Also See: 
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References: 
+++ Description:
+++ \axiomType{RealRootCharacterizationCategory} provides common acces
+++ functions for all real root codings.
+RealRootCharacterizationCategory(TheField, ThePols ) : Category == PUB where
+
+   TheField : Join(OrderedRing, Field)
+   ThePols : UnivariatePolynomialCategory(TheField)
+
+   Z ==> Integer
+   N ==> PositiveInteger
+
+   PUB ==>
+     SetCategory with
+
+        sign:                ( ThePols, $ )   ->            Z
+              ++ \axiom{sign(pol,aRoot)} gives the sign of \axiom{pol}
+              ++ interpreted as \axiom{aRoot}
+        zero? :              ( ThePols, $ )   ->         Boolean
+              ++ \axiom{zero?(pol,aRoot)} answers if \axiom{pol}
+              ++ interpreted as \axiom{aRoot} is \axiom{0}
+        negative?:           ( ThePols, $ )   ->         Boolean
+              ++ \axiom{negative?(pol,aRoot)} answers if \axiom{pol}
+              ++ interpreted as \axiom{aRoot} is negative
+        positive?:           ( ThePols, $ )   ->         Boolean
+              ++ \axiom{positive?(pol,aRoot)} answers if \axiom{pol}
+              ++ interpreted as \axiom{aRoot} is positive
+        recip:               ( ThePols, $ )   ->   Union(ThePols,"failed") 
+              ++ \axiom{recip(pol,aRoot)} tries to inverse \axiom{pol}
+              ++ interpreted as \axiom{aRoot}
+        definingPolynomial:         $         ->         ThePols
+              ++ \axiom{definingPolynomial(aRoot)} gives a polynomial
+              ++ such that \axiom{definingPolynomial(aRoot).aRoot = 0} 
+        allRootsOf:              ThePols      ->          List $
+              ++ \axiom{allRootsOf(pol)} creates all the roots of \axiom{pol} 
+              ++ in the Real Closure, assumed in order.
+        rootOf:              ( ThePols, N )   ->      Union($,"failed")
+              ++ \axiom{rootOf(pol,n)} gives the nth root for the order of the
+              ++ Real Closure
+        approximate :  (ThePols,$,TheField)   ->    TheField
+              ++ \axiom{approximate(term,root,prec)} gives an approximation 
+              ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
+
+        relativeApprox :  (ThePols,$,TheField)   ->    TheField
+              ++ \axiom{approximate(term,root,prec)} gives an approximation 
+              ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
+
+      add
+
+        zero?(toTest, rootChar) == 
+          sign(toTest, rootChar) = 0
+                
+        negative?(toTest, rootChar) == 
+          sign(toTest, rootChar) < 0              
+        
+        positive?(toTest, rootChar) == 
+          sign(toTest, rootChar) > 0
+
+        rootOf(pol,n) ==
+          liste:List($):= allRootsOf(pol)
+          # liste > n => "failed"
+          liste.n
+
+        recip(toInv,rootChar) ==
+          degree(toInv) = 0 => 
+            res := recip(leadingCoefficient(toInv))
+            if (res case "failed") then "failed" else (res::TheField::ThePols)
+          defPol := definingPolynomial(rootChar)
+          d := principalIdeal([defPol,toInv])
+          zero?(d.generator,rootChar) => "failed"
+          if (degree(d.generator) ^= 0 )
+          then
+            defPol := (defPol exquo (d.generator))::ThePols
+            d := principalIdeal([defPol,toInv])
+          d.coef.2
+
+@
+<<RRCC.dotabb>>=
+"RRCC"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RRCC"];
+"RRCC" -> "SETCAT"
+
+@
+<<RRCC.dotfull>>=
+"RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RRCC"];
+"RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))"
+  -> "SetCategory()"
+
+@
+<<RRCC.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))"
+ [color=lightblue];
+"RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))"
+  -> "SetCategory()"
+
+"SetCategory()" [color=lightblue];
+"SetCategory()" -> "BasicType()"
+"SetCategory()" -> "CoercibleTo(OutputForm)"
+
+"BasicType()" [color=lightblue];
+"BasicType()" -> "Category"
+
+"CoercibleTo(OutputForm)" [color=seagreen];
+"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+
+"CoercibleTo(a:Type)" [color=lightblue];
+"CoercibleTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{SegmentExpansionCategory}{SEGXCAT}
 \pagepic{ps/v102segmentexpansioncategory.ps}{SEGXCAT}{0.75}
 
@@ -6543,6 +6941,7 @@ SegmentExpansionCategory(S: OrderedRing, L: StreamAggregate(S)): Category ==
 "SEGXCAT"
  [color=lightblue,href="bookvol10.2.pdf#nameddest=SEGXCAT"];
 "SEGXCAT" -> "SEGCAT"
+
 @
 <<SEGXCAT.dotfull>>=
 "SegmentExpansionCategory(a:OrderedRing,b:StreamAggregate(OrderedRing))"
@@ -11891,6 +12290,797 @@ digraph pic {
 
 }
 @
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{MatrixCategory}{MATCAT}
+\pagepic{ps/v102matrixcategory.ps}{MATCAT}{0.60}
+
+{\bf See:}\\
+\pagefrom{TwoDimensionalArrayCategory}{ARR2CAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{MATCAT}{antisymmetric?} &
+\cross{MATCAT}{any?} &
+\cross{MATCAT}{coerce} &
+\cross{MATCAT}{column} &
+\cross{MATCAT}{copy} \\
+\cross{MATCAT}{count} &
+\cross{MATCAT}{determinant} &
+\cross{MATCAT}{diagonal?} &
+\cross{MATCAT}{diagonalMatrix} &
+\cross{MATCAT}{elt} \\
+\cross{MATCAT}{empty} &
+\cross{MATCAT}{empty?} &
+\cross{MATCAT}{eq?} &
+\cross{MATCAT}{eval} &
+\cross{MATCAT}{every?} \\
+\cross{MATCAT}{exquo} &
+\cross{MATCAT}{fill!} &
+\cross{MATCAT}{hash} &
+\cross{MATCAT}{horizConcat} &
+\cross{MATCAT}{inverse} \\
+\cross{MATCAT}{latex} &
+\cross{MATCAT}{less?} &
+\cross{MATCAT}{listOfLists} &
+\cross{MATCAT}{map} &
+\cross{MATCAT}{map!} \\
+\cross{MATCAT}{matrix} &
+\cross{MATCAT}{maxColIndex} &
+\cross{MATCAT}{maxRowIndex} &
+\cross{MATCAT}{member?} &
+\cross{MATCAT}{members} \\
+\cross{MATCAT}{minColIndex} &
+\cross{MATCAT}{minordet} &
+\cross{MATCAT}{minRowIndex} &
+\cross{MATCAT}{more?} &
+\cross{MATCAT}{ncols} \\
+\cross{MATCAT}{new} &
+\cross{MATCAT}{nrows} &
+\cross{MATCAT}{nullSpace} &
+\cross{MATCAT}{nullity} &
+\cross{MATCAT}{parts} \\
+\cross{MATCAT}{qelt} &
+\cross{MATCAT}{qsetelt!} &
+\cross{MATCAT}{rank} &
+\cross{MATCAT}{row} &
+\cross{MATCAT}{rowEchelon} \\
+\cross{MATCAT}{sample} &
+\cross{MATCAT}{scalarMatrix} &
+\cross{MATCAT}{setColumn!} &
+\cross{MATCAT}{setelt} &
+\cross{MATCAT}{setRow!} \\
+\cross{MATCAT}{setsubMatrix!} &
+\cross{MATCAT}{size?} &
+\cross{MATCAT}{square?} &
+\cross{MATCAT}{squareTop} &
+\cross{MATCAT}{subMatrix} \\
+\cross{MATCAT}{swapColumns!} &
+\cross{MATCAT}{swapRows!} &
+\cross{MATCAT}{symmetric?} &
+\cross{MATCAT}{transpose} &
+\cross{MATCAT}{vertConcat} \\
+\cross{MATCAT}{zero} &
+\cross{MATCAT}{\#?} &
+\cross{MATCAT}{?**?} &
+\cross{MATCAT}{?/?} &
+\cross{MATCAT}{?=?} \\
+\cross{MATCAT}{?\~{}=?} &
+\cross{MATCAT}{?*?} &
+\cross{MATCAT}{?+?} &
+\cross{MATCAT}{-?} &
+\cross{MATCAT}{?-?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{MATCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{MATCAT}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf nil}
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ determinant : % -> R if R has commutative *
+ inverse : % -> Union(%,"failed") if R has FIELD
+ minordet : % -> R if R has commutative *
+ nullity : % -> NonNegativeInteger if R has INTDOM
+ nullSpace : % -> List Col if R has INTDOM
+ rowEchelon : % -> % if R has EUCDOM
+ rank : % -> NonNegativeInteger if R has INTDOM
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ antisymmetric? : % -> Boolean
+ coerce : Col -> %                    
+ diagonal? : % -> Boolean
+ diagonalMatrix : List % -> %         
+ diagonalMatrix : List R -> %
+ elt : (%,List Integer,List Integer) -> %
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ horizConcat : (%,%) -> %             
+ listOfLists : % -> List List R
+ matrix : List List R -> %            
+ scalarMatrix : (NonNegativeInteger,R) -> %
+ setelt : (%,List Integer,List Integer,%) -> %
+ setsubMatrix! : (%,Integer,Integer,%) -> %
+ square? : % -> Boolean               
+ squareTop : % -> %
+ subMatrix : (%,Integer,Integer,Integer,Integer) -> %
+ swapColumns! : (%,Integer,Integer) -> %
+ swapRows! : (%,Integer,Integer) -> %
+ symmetric? : % -> Boolean            
+ transpose : Row -> %                 
+ transpose : % -> %
+ vertConcat : (%,%) -> %
+ zero : (NonNegativeInteger,NonNegativeInteger) -> %
+ ?/? : (%,R) -> % if R has FIELD
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %                     
+ -? : % -> %
+ ?*? : (%,R) -> %
+ ?*? : (R,%) -> %                     
+ ?*? : (Integer,%) -> %               
+ ?**? : (%,NonNegativeInteger) -> %
+ ?**? : (%,Integer) -> % if R has FIELD
+ ?*? : (%,Col) -> Col
+ ?*? : (Row,%) -> Row                 
+ ?*? : (%,%) -> %
+\end{verbatim}
+
+These exports come from \refto{TwoDimensionalArrayCategory}(R,Row,Col)\\
+where R:Ring, Row:FiniteLinearAggregate(R),\\
+Col:FiniteLinearAggregate(R):
+\begin{verbatim}
+ any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ coerce : % -> OutputForm if R has SETCAT
+ column : (%,Integer) -> Col
+ copy : % -> %                        
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ elt : (%,Integer,Integer,R) -> R     
+ elt : (%,Integer,Integer) -> R
+ empty : () -> %                      
+ empty? : % -> Boolean
+ eq? : (%,%) -> Boolean               
+ eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ fill! : (%,R) -> %
+ hash : % -> SingleInteger if R has SETCAT
+ latex : % -> String if R has SETCAT
+ less? : (%,NonNegativeInteger) -> Boolean
+ map : (((R,R) -> R),%,%,R) -> %      
+ map : (((R,R) -> R),%,%) -> %
+ map : ((R -> R),%) -> %              
+ map! : ((R -> R),%) -> %
+ maxColIndex : % -> Integer
+ maxRowIndex : % -> Integer           
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ members : % -> List R if $ has finiteAggregate
+ minColIndex : % -> Integer
+ minRowIndex : % -> Integer           
+ more? : (%,NonNegativeInteger) -> Boolean
+ new : (NonNegativeInteger,NonNegativeInteger,R) -> %
+ ncols : % -> NonNegativeInteger
+ nrows : % -> NonNegativeInteger      
+ parts : % -> List R
+ qelt : (%,Integer,Integer) -> R      
+ qsetelt! : (%,Integer,Integer,R) -> R
+ row : (%,Integer) -> Row
+ sample : () -> %                     
+ setColumn! : (%,Integer,Col) -> %
+ setelt : (%,Integer,Integer,R) -> R
+ setRow! : (%,Integer,Row) -> %
+ size? : (%,NonNegativeInteger) -> Boolean
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?~=? : (%,%) -> Boolean if R has SETCAT
+ ?=? : (%,%) -> Boolean if R has SETCAT
+\end{verbatim}
+
+<<category MATCAT MatrixCategory>>=
+)abbrev category MATCAT MatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: Matrix(R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{MatrixCategory} is a general matrix category which allows
+++   different representations and indexing schemes.  Rows and
+++   columns may be extracted with rows returned as objects of
+++   type Row and colums returned as objects of type Col.
+++   A domain belonging to this category will be shallowly mutable.
+++   The index of the 'first' row may be obtained by calling the
+++   function \spadfun{minRowIndex}.  The index of the 'first' column may
+++   be obtained by calling the function \spadfun{minColIndex}.  The index of
+++   the first element of a Row is the same as the index of the
+++   first column in a matrix and vice versa.
+MatrixCategory(R,Row,Col): Category == Definition where
+  R   : Ring
+  Row : FiniteLinearAggregate R
+  Col : FiniteLinearAggregate R
+
+  Definition ==> TwoDimensionalArrayCategory(R,Row,Col) with
+     shallowlyMutable
+       ++ One may destructively alter matrices
+
+     finiteAggregate
+       ++ matrices are finite
+
+--% Predicates
+
+     square?  : % -> Boolean
+       ++ \spad{square?(m)} returns true if m is a square matrix
+       ++ (if m has the same number of rows as columns) and false otherwise.
+     diagonal?: % -> Boolean
+       ++ \spad{diagonal?(m)} returns true if the matrix m is square and
+       ++ diagonal (i.e. all entries of m not on the diagonal are zero) and
+       ++ false otherwise.
+     symmetric?: % -> Boolean
+       ++ \spad{symmetric?(m)} returns true if the matrix m is square and
+       ++ symmetric (i.e. \spad{m[i,j] = m[j,i]} for all i and j) and false
+       ++ otherwise.
+     antisymmetric?: % -> Boolean
+       ++ \spad{antisymmetric?(m)} returns true if the matrix m is square and
+       ++ antisymmetric (i.e. \spad{m[i,j] = -m[j,i]} for all i and j) 
+       ++ and false otherwise.
+
+--% Creation
+
+     zero: (NonNegativeInteger,NonNegativeInteger) -> %
+       ++ \spad{zero(m,n)} returns an m-by-n zero matrix.
+     matrix: List List R -> %
+       ++ \spad{matrix(l)} converts the list of lists l to a matrix, where the
+       ++ list of lists is viewed as a list of the rows of the matrix.
+     scalarMatrix: (NonNegativeInteger,R) -> %
+       ++ \spad{scalarMatrix(n,r)} returns an n-by-n matrix with r's on the
+       ++ diagonal and zeroes elsewhere.
+     diagonalMatrix: List R -> %
+       ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
+       ++ of l on the diagonal.
+     diagonalMatrix: List % -> %
+       ++ \spad{diagonalMatrix([m1,...,mk])} creates a block diagonal matrix
+       ++ M with block matrices {\em m1},...,{\em mk} down the diagonal,
+       ++ with 0 block matrices elsewhere.
+       ++ More precisly: if \spad{ri := nrows mi}, \spad{ci := ncols mi},
+       ++ then m is an (r1+..+rk) by (c1+..+ck) - matrix  with entries
+       ++ \spad{m.i.j = ml.(i-r1-..-r(l-1)).(j-n1-..-n(l-1))}, if
+       ++ \spad{(r1+..+r(l-1)) < i <= r1+..+rl} and
+       ++ \spad{(c1+..+c(l-1)) < i <= c1+..+cl},
+       ++ \spad{m.i.j} = 0  otherwise.
+     coerce: Col -> %
+       ++ \spad{coerce(col)} converts the column col to a column matrix.
+     transpose: Row -> %
+       ++ \spad{transpose(r)} converts the row r to a row matrix.
+
+--% Creation of new matrices from old
+
+     transpose: % -> %
+       ++ \spad{transpose(m)} returns the transpose of the matrix m.
+     squareTop: % -> %
+       ++ \spad{squareTop(m)} returns an n-by-n matrix consisting of the first
+       ++ n rows of the m-by-n matrix m. Error: if
+       ++ \spad{m < n}.
+     horizConcat: (%,%) -> %
+       ++ \spad{horizConcat(x,y)} horizontally concatenates two matrices with
+       ++ an equal number of rows. The entries of y appear to the right
+       ++ of the entries of x.  Error: if the matrices
+       ++ do not have the same number of rows.
+     vertConcat: (%,%) -> %
+       ++ \spad{vertConcat(x,y)} vertically concatenates two matrices with an
+       ++ equal number of columns. The entries of y appear below
+       ++ of the entries of x.  Error: if the matrices
+       ++ do not have the same number of columns.
+
+--% Part extractions/assignments
+
+     listOfLists: % -> List List R
+       ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
+       ++ of lists.
+     elt: (%,List Integer,List Integer) -> %
+       ++ \spad{elt(x,rowList,colList)} returns an m-by-n matrix consisting
+       ++ of elements of x, where \spad{m = # rowList} and \spad{n = # colList}
+       ++ If \spad{rowList = [i<1>,i<2>,...,i<m>]} and \spad{colList =
+       ++ [j<1>,j<2>,...,j<n>]}, then the \spad{(k,l)}th entry of
+       ++ \spad{elt(x,rowList,colList)} is \spad{x(i<k>,j<l>)}.
+     setelt: (%,List Integer,List Integer, %) -> %
+       ++ \spad{setelt(x,rowList,colList,y)} destructively alters the matrix x.
+       ++ If y is \spad{m}-by-\spad{n}, \spad{rowList = [i<1>,i<2>,...,i<m>]}
+       ++ and \spad{colList = [j<1>,j<2>,...,j<n>]}, then \spad{x(i<k>,j<l>)}
+       ++ is set to \spad{y(k,l)} for \spad{k = 1,...,m} and \spad{l = 1,...,n}
+     swapRows_!: (%,Integer,Integer) -> %
+       ++ \spad{swapRows!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
+       ++ rows of m. This destructively alters the matrix.
+     swapColumns_!: (%,Integer,Integer) -> %
+       ++ \spad{swapColumns!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
+       ++ columns of m. This destructively alters the matrix.
+     subMatrix: (%,Integer,Integer,Integer,Integer) -> %
+       ++ \spad{subMatrix(x,i1,i2,j1,j2)} extracts the submatrix
+       ++ \spad{[x(i,j)]} where the index i ranges from \spad{i1} to \spad{i2}
+       ++ and the index j ranges from \spad{j1} to \spad{j2}.
+     setsubMatrix_!: (%,Integer,Integer,%) -> %
+       ++ \spad{setsubMatrix(x,i1,j1,y)} destructively alters the
+       ++ matrix x. Here \spad{x(i,j)} is set to \spad{y(i-i1+1,j-j1+1)} for
+       ++ \spad{i = i1,...,i1-1+nrows y} and \spad{j = j1,...,j1-1+ncols y}.
+
+--% Arithmetic
+
+     "+": (%,%) -> %
+       ++ \spad{x + y} is the sum of the matrices x and y.
+       ++ Error: if the dimensions are incompatible.
+     "-": (%,%) -> %
+       ++ \spad{x - y} is the difference of the matrices x and y.
+       ++ Error: if the dimensions are incompatible.
+     "-":  %    -> %
+       ++ \spad{-x} returns the negative of the matrix x.
+     "*": (%,%) -> %
+       ++ \spad{x * y} is the product of the matrices x and y.
+       ++ Error: if the dimensions are incompatible.
+     "*": (R,%) -> %
+       ++ \spad{r*x} is the left scalar multiple of the scalar r and the
+       ++ matrix x.
+     "*": (%,R) -> %
+       ++ \spad{x * r} is the right scalar multiple of the scalar r and the
+       ++ matrix x.
+     "*": (Integer,%) -> %
+       ++ \spad{n * x} is an integer multiple.
+     "*": (%,Col) -> Col
+       ++ \spad{x * c} is the product of the matrix x and the column vector c.
+       ++ Error: if the dimensions are incompatible.
+     "*": (Row,%) -> Row
+       ++ \spad{r * x} is the product of the row vector r and the matrix x.
+       ++ Error: if the dimensions are incompatible.
+     "**": (%,NonNegativeInteger) -> %
+       ++ \spad{x ** n} computes a non-negative integral power of the matrix x.
+       ++ Error: if the matrix is not square.
+     if R has IntegralDomain then
+       "exquo": (%,R) -> Union(%,"failed")
+         ++ \spad{exquo(m,r)} computes the exact quotient of the elements
+         ++ of m by r, returning \axiom{"failed"} if this is not possible.
+     if R has Field then
+       "/": (%,R) -> %
+         ++ \spad{m/r} divides the elements of m by r. Error: if \spad{r = 0}.
+
+--% Linear algebra
+
+     if R has EuclideanDomain then
+       rowEchelon: % -> %
+         ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+     if R has IntegralDomain then
+       rank: % -> NonNegativeInteger
+         ++ \spad{rank(m)} returns the rank of the matrix m.
+       nullity: % -> NonNegativeInteger
+         ++ \spad{nullity(m)} returns the nullity of the matrix m. This is
+         ++ the dimension of the null space of the matrix m.
+       nullSpace: % -> List Col
+         ++ \spad{nullSpace(m)} returns a basis for the null space of
+         ++ the matrix m.
+     if R has commutative("*") then
+       determinant: % -> R
+         ++ \spad{determinant(m)} returns the determinant of the matrix m.
+         ++ Error: if the matrix is not square.
+       minordet: % -> R
+         ++ \spad{minordet(m)} computes the determinant of the matrix m using
+         ++ minors. Error: if the matrix is not square.
+     if R has Field then
+       inverse: % -> Union(%,"failed")
+         ++ \spad{inverse(m)} returns the inverse of the matrix m.
+         ++ If the matrix is not invertible, "failed" is returned.
+         ++ Error: if the matrix is not square.
+       "**": (%,Integer) -> %
+         ++ \spad{m**n} computes an integral power of the matrix m.
+         ++ Error: if matrix is not square or if the matrix
+         ++ is square but not invertible.
+
+   add
+     minr ==> minRowIndex
+     maxr ==> maxRowIndex
+     minc ==> minColIndex
+     maxc ==> maxColIndex
+     mini ==> minIndex
+     maxi ==> maxIndex
+
+--% Predicates
+
+     square? x == nrows x = ncols x
+
+     diagonal? x ==
+       not square? x => false
+       for i in minr x .. maxr x repeat
+         for j in minc x .. maxc x | (j - minc x) ^= (i - minr x) repeat
+           not zero? qelt(x, i, j) => return false
+       true
+
+     symmetric? x ==
+       (nRows := nrows x) ^= ncols x => false
+       mr := minRowIndex x; mc := minColIndex x
+       for i in 0..(nRows - 1) repeat
+         for j in (i + 1)..(nRows - 1) repeat
+           qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
+       true
+
+     antisymmetric? x ==
+       (nRows := nrows x) ^= ncols x => false
+       mr := minRowIndex x; mc := minColIndex x
+       for i in 0..(nRows - 1) repeat
+         for j in i..(nRows - 1) repeat
+           qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
+             return false
+       true
+
+--% Creation of matrices
+
+     zero(rows,cols) == new(rows,cols,0)
+
+     matrix(l: List List R) ==
+       null l => new(0,0,0)
+       -- error check: this is a top level function
+       rows : NonNegativeInteger := 1; cols := # first l
+       cols = 0 => error "matrices with zero columns are not supported"
+       for ll in rest l repeat
+         cols ^= # ll => error "matrix: rows of different lengths"
+         rows := rows + 1
+       ans := new(rows,cols,0)
+       for i in minr(ans)..maxr(ans) for ll in l repeat
+         for j in minc(ans)..maxc(ans) for r in ll repeat
+           qsetelt_!(ans,i,j,r)
+       ans
+
+     scalarMatrix(n,r) ==
+       ans := zero(n,n)
+       for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) repeat
+         qsetelt_!(ans,i,j,r)
+       ans
+
+     diagonalMatrix(l: List R) ==
+       n := #l; ans := zero(n,n)
+       for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) _
+           for r in l repeat qsetelt_!(ans,i,j,r)
+       ans
+
+     diagonalMatrix(list: List %) ==
+       rows : NonNegativeInteger := 0
+       cols : NonNegativeInteger := 0
+       for mat in list repeat
+         rows := rows + nrows mat
+         cols := cols + ncols mat
+       ans := zero(rows,cols)
+       loR := minr ans; loC := minc ans
+       for mat in list repeat
+         hiR := loR + nrows(mat) - 1; hiC := loC + nrows(mat) - 1
+         for i in loR..hiR for k in minr(mat)..maxr(mat) repeat
+           for j in loC..hiC for l in minc(mat)..maxc(mat) repeat
+             qsetelt_!(ans,i,j,qelt(mat,k,l))
+         loR := hiR + 1; loC := hiC + 1
+       ans
+
+     coerce(v:Col) ==
+       x := new(#v,1,0)
+       one := minc(x)
+       for i in minr(x)..maxr(x) for k in mini(v)..maxi(v) repeat
+         qsetelt_!(x,i,one,qelt(v,k))
+       x
+
+     transpose(v:Row) ==
+       x := new(1,#v,0)
+       one := minr(x)
+       for j in minc(x)..maxc(x) for k in mini(v)..maxi(v) repeat
+         qsetelt_!(x,one,j,qelt(v,k))
+       x
+
+     transpose(x:%) ==
+       ans := new(ncols x,nrows x,0)
+       for i in minr(ans)..maxr(ans) repeat
+         for j in minc(ans)..maxc(ans) repeat
+           qsetelt_!(ans,i,j,qelt(x,j,i))
+       ans
+
+     squareTop x ==
+       nrows x < (cols := ncols x) =>
+         error "squareTop: number of columns exceeds number of rows"
+       ans := new(cols,cols,0)
+       for i in minr(x)..(minr(x) + cols - 1) repeat
+         for j in minc(x)..maxc(x) repeat
+           qsetelt_!(ans,i,j,qelt(x,i,j))
+       ans
+
+     horizConcat(x,y) ==
+       (rows := nrows x) ^= nrows y =>
+         error "HConcat: matrices must have same number of rows"
+       ans := new(rows,(cols := ncols x) + ncols y,0)
+       for i in minr(x)..maxr(x) repeat
+         for j in minc(x)..maxc(x) repeat
+           qsetelt_!(ans,i,j,qelt(x,i,j))
+       for i in minr(y)..maxr(y) repeat
+         for j in minc(y)..maxc(y) repeat
+           qsetelt_!(ans,i,j + cols,qelt(y,i,j))
+       ans
+
+     vertConcat(x,y) ==
+       (cols := ncols x) ^= ncols y =>
+         error "HConcat: matrices must have same number of columns"
+       ans := new((rows := nrows x) + nrows y,cols,0)
+       for i in minr(x)..maxr(x) repeat
+         for j in minc(x)..maxc(x) repeat
+           qsetelt_!(ans,i,j,qelt(x,i,j))
+       for i in minr(y)..maxr(y) repeat
+         for j in minc(y)..maxc(y) repeat
+           qsetelt_!(ans,i + rows,j,qelt(y,i,j))
+       ans
+
+--% Part extraction/assignment
+
+     listOfLists x ==
+       ll : List List R := nil()
+       for i in maxr(x)..minr(x) by -1 repeat
+         l : List R := nil()
+         for j in maxc(x)..minc(x) by -1 repeat
+           l := cons(qelt(x,i,j),l)
+         ll := cons(l,ll)
+       ll
+
+     swapRows_!(x,i1,i2) ==
+       (i1 < minr(x)) or (i1 > maxr(x)) or (i2 < minr(x)) or _
+           (i2 > maxr(x)) => error "swapRows!: index out of range"
+       i1 = i2 => x
+       for j in minc(x)..maxc(x) repeat
+         r := qelt(x,i1,j)
+         qsetelt_!(x,i1,j,qelt(x,i2,j))
+         qsetelt_!(x,i2,j,r)
+       x
+
+     swapColumns_!(x,j1,j2) ==
+       (j1 < minc(x)) or (j1 > maxc(x)) or (j2 < minc(x)) or _
+           (j2 > maxc(x)) => error "swapColumns!: index out of range"
+       j1 = j2 => x
+       for i in minr(x)..maxr(x) repeat
+         r := qelt(x,i,j1)
+         qsetelt_!(x,i,j1,qelt(x,i,j2))
+         qsetelt_!(x,i,j2,r)
+       x
+
+     elt(x:%,rowList:List Integer,colList:List Integer) ==
+       for ei in rowList repeat
+         (ei < minr(x)) or (ei > maxr(x)) =>
+           error "elt: index out of range"
+       for ej in colList repeat
+         (ej < minc(x)) or (ej > maxc(x)) =>
+           error "elt: index out of range"
+       y := new(# rowList,# colList,0)
+       for ei in rowList for i in minr(y)..maxr(y) repeat
+         for ej in colList for j in minc(y)..maxc(y) repeat
+           qsetelt_!(y,i,j,qelt(x,ei,ej))
+       y
+
+     setelt(x:%,rowList:List Integer,colList:List Integer,y:%) ==
+       for ei in rowList repeat
+         (ei < minr(x)) or (ei > maxr(x)) =>
+           error "setelt: index out of range"
+       for ej in colList repeat
+         (ej < minc(x)) or (ej > maxc(x)) =>
+           error "setelt: index out of range"
+       ((# rowList) ^= (nrows y)) or ((# colList) ^= (ncols y)) =>
+         error "setelt: matrix has bad dimensions"
+       for ei in rowList for i in minr(y)..maxr(y) repeat
+         for ej in colList for j in minc(y)..maxc(y) repeat
+           qsetelt_!(x,ei,ej,qelt(y,i,j))
+       y
+
+     subMatrix(x,i1,i2,j1,j2) ==
+       (i2 < i1) => error "subMatrix: bad row indices"
+       (j2 < j1) => error "subMatrix: bad column indices"
+       (i1 < minr(x)) or (i2 > maxr(x)) =>
+         error "subMatrix: index out of range"
+       (j1 < minc(x)) or (j2 > maxc(x)) =>
+         error "subMatrix: index out of range"
+       rows := (i2 - i1 + 1) pretend NonNegativeInteger
+       cols := (j2 - j1 + 1) pretend NonNegativeInteger
+       y := new(rows,cols,0)
+       for i in minr(y)..maxr(y) for k in i1..i2 repeat
+         for j in minc(y)..maxc(y) for l in j1..j2 repeat
+           qsetelt_!(y,i,j,qelt(x,k,l))
+       y
+
+     setsubMatrix_!(x,i1,j1,y) ==
+       i2 := i1 + nrows(y) -1
+       j2 := j1 + ncols(y) -1
+       (i1 < minr(x)) or (i2 > maxr(x)) =>
+        error _
+         "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
+       (j1 < minc(x)) or (j2 > maxc(x)) =>
+        error _
+         "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
+       for i in minr(y)..maxr(y) for k in i1..i2 repeat
+         for j in minc(y)..maxc(y) for l in j1..j2 repeat
+           qsetelt_!(x,k,l,qelt(y,i,j))
+       x
+
+--% Arithmetic
+
+     x + y ==
+       ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
+         error "can't add matrices of different dimensions"
+       ans := new(r,c,0)
+       for i in minr(x)..maxr(x) repeat
+         for j in minc(x)..maxc(x) repeat
+           qsetelt_!(ans,i,j,qelt(x,i,j) + qelt(y,i,j))
+       ans
+
+     x - y ==
+       ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
+         error "can't subtract matrices of different dimensions"
+       ans := new(r,c,0)
+       for i in minr(x)..maxr(x) repeat
+         for j in minc(x)..maxc(x) repeat
+           qsetelt_!(ans,i,j,qelt(x,i,j) - qelt(y,i,j))
+       ans
+
+     - x == map(- #1,x)
+
+     a:R * x:% == map(a * #1,x)
+
+     x:% * a:R == map(#1 * a,x)
+
+     m:Integer * x:% == map(m * #1,x)
+
+     x:% * y:% ==
+       (ncols x ^= nrows y) =>
+         error "can't multiply matrices of incompatible dimensions"
+       ans := new(nrows x,ncols y,0)
+       for i in minr(x)..maxr(x) repeat
+         for j in minc(y)..maxc(y) repeat
+           entry :=
+             sum : R := 0
+             for k in minr(y)..maxr(y) for l in minc(x)..maxc(x) repeat
+               sum := sum + qelt(x,i,l) * qelt(y,k,j)
+             sum
+           qsetelt_!(ans,i,j,entry)
+       ans
+
+     positivePower:(%,Integer) -> %
+     positivePower(x,n) ==
+--       one? n => x
+       (n = 1) => x
+       odd? n => x * positivePower(x,n - 1)
+       y := positivePower(x,n quo 2)
+       y * y
+
+     x:% ** n:NonNegativeInteger ==
+       not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
+       zero? n => scalarMatrix(nn,1)
+       positivePower(x,n)
+
+     --if R has ConvertibleTo InputForm then
+       --convert(x:%):InputForm ==
+         --convert [convert("matrix"::Symbol)@InputForm,
+                  --convert listOfLists x]$List(InputForm)
+
+     if Col has shallowlyMutable then
+
+       x:% * v:Col ==
+         ncols(x) ^= #v =>
+           error "can't multiply matrix A and vector v if #cols A ^= #v"
+         w : Col := new(nrows x,0)
+         for i in minr(x)..maxr(x) for k in mini(w)..maxi(w) repeat
+           w.k :=
+             sum : R := 0
+             for j in minc(x)..maxc(x) for l in mini(v)..maxi(v) repeat
+               sum := sum + qelt(x,i,j) * v(l)
+             sum
+         w
+
+     if Row has shallowlyMutable then
+
+       v:Row * x:% ==
+         nrows(x) ^= #v =>
+           error "can't multiply vector v and matrix A if #rows A ^= #v"
+         w : Row := new(ncols x,0)
+         for j in minc(x)..maxc(x) for k in mini(w)..maxi(w) repeat
+           w.k :=
+             sum : R := 0
+             for i in minr(x)..maxr(x) for l in mini(v)..maxi(v) repeat
+               sum := sum + qelt(x,i,j) * v(l)
+             sum
+         w
+
+     if R has IntegralDomain then
+       x exquo a ==
+         ans := new(nrows x,ncols x,0)
+         for i in minr(x)..maxr(x) repeat
+           for j in minc(x)..maxc(x) repeat
+             entry :=
+               (r := (qelt(x,i,j) exquo a)) case "failed" =>
+                 return "failed"
+               r :: R
+             qsetelt_!(ans,i,j,entry)
+         ans
+
+     if R has Field then
+       x / r == map(#1 / r,x)
+
+       x:% ** n:Integer ==
+         not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
+         zero? n => scalarMatrix(nn,1)
+         positive? n => positivePower(x,n)
+         (xInv := inverse x) case "failed" =>
+           error "**: matrix must be invertible"
+         positivePower(xInv :: %,-n)
+
+@
+<<MATCAT.dotabb>>=
+"MATCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MATCAT"];
+"MATCAT" -> "ARR2CAT"
+
+@
+<<MATCAT.dotfull>>=
+"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MATCAT"];
+"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)"
+ ->
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+
+@
+<<MATCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)" 
+ [color=lightblue];
+"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)"
+ ->
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+ [color=lightblue];
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+    -> "HomogeneousAggregate(a:Type)"
+
+"HomogeneousAggregate(a:Type)" [color=lightblue];
+"HomogeneousAggregate(a:Type)" -> "Aggregate()"
+"HomogeneousAggregate(a:Type)" -> "Evalable(a:Type)"
+"HomogeneousAggregate(a:Type)" -> "SetCategory()"
+
+"Evalable(a:Type)" [color="#00EE00"];
+
+"SetCategory()" [color=lightblue];
+"SetCategory()" -> "BasicType()"
+"SetCategory()" -> "CoercibleTo(OutputForm)"
+
+"BasicType()" [color=lightblue];
+"BasicType()" -> "Category"
+
+"CoercibleTo(OutputForm)" [color=seagreen];
+"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+
+"CoercibleTo(a:Type)" [color=lightblue];
+"CoercibleTo(a:Type)" -> "Category"
+
+"Aggregate()" [color=lightblue];
+"Aggregate()" -> "Type()"
+
+"Type()" [color=lightblue];
+"Type()" -> "Category"
+
+"Category" [color=lightblue];
+
+}
+
+@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OrderedAbelianSemiGroup}{OASGP}
 \pagepic{ps/v102orderedabeliansemigroup.ps}{OASGP}{0.75}
@@ -17563,6 +18753,7 @@ FiniteDivisorCategory(F, UP, UPUP, R): Category == Result where
 "FDIVCAT"
  [color=lightblue,href="bookvol10.2.pdf#nameddest=FDIVCAT"];
 "FDIVCAT" -> "ABELGRP"
+
 @
 <<FDIVCAT.dotfull>>=
 "FiniteDivisorCategory()" 
@@ -21567,1380 +22758,8 @@ digraph pic {
 }
 
 @
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{StringAggregate}{SRAGG}
-\pagepic{ps/v102stringaggregate.ps}{SRAGG}{1.00}
-
-{\bf See:}\\
-\pageto{StringCategory}{STRICAT}
-\pagefrom{OneDimensionalArrayAggregate}{A1AGG}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{SRAGG}{any?} &
-\cross{SRAGG}{coerce} &
-\cross{SRAGG}{concat} &
-\cross{SRAGG}{construct} &
-\cross{SRAGG}{copy} \\
-\cross{SRAGG}{convert} &
-\cross{SRAGG}{copyInto!} &
-\cross{SRAGG}{count} &
-\cross{SRAGG}{delete} &
-\cross{SRAGG}{?.?} \\
-\cross{SRAGG}{elt} &
-\cross{SRAGG}{empty} &
-\cross{SRAGG}{empty?} &
-\cross{SRAGG}{entries} &
-\cross{SRAGG}{entry?} \\
-\cross{SRAGG}{eval} &
-\cross{SRAGG}{every?} &
-\cross{SRAGG}{eq?} &
-\cross{SRAGG}{fill!} &
-\cross{SRAGG}{find} \\
-\cross{SRAGG}{first} &
-\cross{SRAGG}{hash} &
-\cross{SRAGG}{index?} &
-\cross{SRAGG}{indices} &
-\cross{SRAGG}{insert} \\
-\cross{SRAGG}{latex} &
-\cross{SRAGG}{leftTrim} &
-\cross{SRAGG}{less?} &
-\cross{SRAGG}{lowerCase} &
-\cross{SRAGG}{lowerCase!} \\
-\cross{SRAGG}{map} &
-\cross{SRAGG}{map!} &
-\cross{SRAGG}{match} &
-\cross{SRAGG}{match?} &
-\cross{SRAGG}{max} \\
-\cross{SRAGG}{maxIndex} &
-\cross{SRAGG}{member?} &
-\cross{SRAGG}{members} &
-\cross{SRAGG}{merge} &
-\cross{SRAGG}{min} \\
-\cross{SRAGG}{minIndex} &
-\cross{SRAGG}{more?} &
-\cross{SRAGG}{new} &
-\cross{SRAGG}{parts} &
-\cross{SRAGG}{position} \\
-\cross{SRAGG}{prefix?} &
-\cross{SRAGG}{qelt} &
-\cross{SRAGG}{qsetelt!} &
-\cross{SRAGG}{reduce} &
-\cross{SRAGG}{remove} \\
-\cross{SRAGG}{removeDuplicates} &
-\cross{SRAGG}{replace} &
-\cross{SRAGG}{reverse} &
-\cross{SRAGG}{reverse!} &
-\cross{SRAGG}{rightTrim} \\
-\cross{SRAGG}{sample} &
-\cross{SRAGG}{setelt} &
-\cross{SRAGG}{size?} &
-\cross{SRAGG}{sort} &
-\cross{SRAGG}{sort!} \\
-\cross{SRAGG}{sorted?} &
-\cross{SRAGG}{split} &
-\cross{SRAGG}{substring?} &
-\cross{SRAGG}{suffix?} &
-\cross{SRAGG}{swap!} \\
-\cross{SRAGG}{trim} &
-\cross{SRAGG}{trim} &
-\cross{SRAGG}{upperCase} &
-\cross{SRAGG}{upperCase!} &
-\cross{SRAGG}{\#?} \\
-\cross{SRAGG}{?\~{}=?} &
-\cross{SRAGG}{?.?} &
-\cross{SRAGG}{?$<$?} &
-\cross{SRAGG}{?$<=$?} &
-\cross{SRAGG}{?=?} \\
-\cross{SRAGG}{?$>$?} &
-\cross{SRAGG}{?$>=$?} &&&
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item {\bf \cross{SRAGG}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf \cross{SRAGG}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf nil}
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- leftTrim : (%,Character) -> %
- leftTrim : (%,CharacterClass) -> %
- lowerCase! : % -> %
- match : (%,%,Character) -> NonNegativeInteger
- match? : (%,%,Character) -> Boolean
- position : (CharacterClass,%,Integer) -> Integer
- position : (%,%,Integer) -> Integer
- replace : (%,UniversalSegment Integer,%) -> %
- rightTrim : (%,Character) -> %
- rightTrim : (%,CharacterClass) -> %
- split : (%,Character) -> List %
- split : (%,CharacterClass) -> List %
- substring? : (%,%,Integer) -> Boolean
- suffix? : (%,%) -> Boolean           
- upperCase! : % -> %                  
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- coerce : Character -> %              
- lowerCase : % -> %                   
- prefix? : (%,%) -> Boolean           
- trim : (%,CharacterClass) -> %
- trim : (%,Character) -> %            
- upperCase : % -> %
- ?.? : (%,%) -> %                     
-\end{verbatim}
-
-These exports come from \refto{OneDimensionalArrayAggregate}(Character):
-\begin{verbatim}
- any? : ((Character -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- coerce : % -> OutputForm if Character has SETCAT
- concat : List % -> %
- concat : (%,%) -> %                  
- concat : (Character,%) -> %
- concat : (%,Character) -> %          
- construct : List Character -> %
- convert : % -> InputForm 
-          if Character has KONVERT INFORM
- copy : % -> %                        
- copyInto! : (%,%,Integer) -> % 
-          if $ has shallowlyMutable
- count : (Character,%) -> NonNegativeInteger 
-          if Character has SETCAT 
-          and $ has finiteAggregate
- count : ((Character -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- delete : (%,Integer) -> %
- delete : (%,UniversalSegment Integer) -> %
- elt : (%,Integer,Character) -> Character
- empty : () -> %                      
- empty? : % -> Boolean
- entries : % -> List Character        
- entry? : (Character,%) -> Boolean 
-          if $ has finiteAggregate 
-          and Character has SETCAT
- eq? : (%,%) -> Boolean
- eval : (%,List Character,List Character) -> % 
-          if Character has EVALAB CHAR 
-          and Character has SETCAT
- eval : (%,Character,Character) -> % 
-          if Character has EVALAB CHAR 
-          and Character has SETCAT
- eval : (%,Equation Character) -> % 
-          if Character has EVALAB CHAR 
-          and Character has SETCAT
- eval : (%,List Equation Character) -> % 
-          if Character has EVALAB CHAR 
-          and Character has SETCAT
- every? : ((Character -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- fill! : (%,Character) -> % 
-          if $ has shallowlyMutable
- find : ((Character -> Boolean),%) -> Union(Character,"failed")
- first : % -> Character 
-          if Integer has ORDSET
- hash : % -> SingleInteger 
-          if Character has SETCAT
- index? : (Integer,%) -> Boolean      
- indices : % -> List Integer
- insert : (Character,%,Integer) -> %
- insert : (%,%,Integer) -> %          
- latex : % -> String if Character has SETCAT
- less? : (%,NonNegativeInteger) -> Boolean
- map : ((Character -> Character),%) -> %
- map : (((Character,Character) -> Character),%,%) -> %
- map! : ((Character -> Character),%) -> % 
-          if $ has shallowlyMutable
- max : (%,%) -> % if Character has ORDSET
- maxIndex : % -> Integer if Integer has ORDSET
- member? : (Character,%) -> Boolean 
-          if Character has SETCAT 
-          and $ has finiteAggregate
- members : % -> List Character 
-          if $ has finiteAggregate
- merge : (%,%) -> % if Character has ORDSET
- merge : (((Character,Character) -> Boolean),%,%) -> %
- min : (%,%) -> % if Character has ORDSET
- minIndex : % -> Integer if Integer has ORDSET
- more? : (%,NonNegativeInteger) -> Boolean
- new : (NonNegativeInteger,Character) -> %
- parts : % -> List Character if $ has finiteAggregate
- position : (Character,%) -> Integer 
-          if Character has SETCAT
- position : ((Character -> Boolean),%) -> Integer
- position : (Character,%,Integer) -> Integer 
-          if Character has SETCAT
- qelt : (%,Integer) -> Character
- qsetelt! : (%,Integer,Character) -> Character 
-          if $ has shallowlyMutable
- reduce : (((Character,Character) -> Character),%) -> Character 
-          if $ has finiteAggregate
- reduce : 
-   (((Character,Character) -> Character),%,Character) -> Character 
-          if $ has finiteAggregate
- reduce : 
-   (((Character,Character) -> Character),%,Character,Character)
-       -> Character 
-          if Character has SETCAT and $ has finiteAggregate
- remove : ((Character -> Boolean),%) -> % 
-          if $ has finiteAggregate
- remove : (Character,%) -> % 
-          if Character has SETCAT 
-          and $ has finiteAggregate
- removeDuplicates : % -> % 
-          if Character has SETCAT 
-          and $ has finiteAggregate
- reverse : % -> %                     
- reverse! : % -> % if $ has shallowlyMutable
- sample : () -> %                     
- select : ((Character -> Boolean),%) -> % 
-          if $ has finiteAggregate
- setelt : (%,UniversalSegment Integer,Character) -> Character 
-          if $ has shallowlyMutable
- sort! : (((Character,Character) -> Boolean),%) -> % 
-          if $ has shallowlyMutable
- sorted? : (((Character,Character) -> Boolean),%) -> Boolean
- setelt : (%,Integer,Character) -> Character 
-          if $ has shallowlyMutable
- size? : (%,NonNegativeInteger) -> Boolean
- sort : % -> % if Character has ORDSET
- sort : (((Character,Character) -> Boolean),%) -> %
- sort! : % -> % 
-          if Character has ORDSET 
-          and $ has shallowlyMutable
- sorted? : % -> Boolean if Character has ORDSET
- swap! : (%,Integer,Integer) -> Void 
-          if $ has shallowlyMutable
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?~=? : (%,%) -> Boolean if Character has SETCAT
- ?.? : (%,UniversalSegment Integer) -> %
- ?.? : (%,Integer) -> Character
- ?<? : (%,%) -> Boolean if Character has ORDSET
- ?<=? : (%,%) -> Boolean if Character has ORDSET
- ?=? : (%,%) -> Boolean if Character has SETCAT
- ?>? : (%,%) -> Boolean if Character has ORDSET
- ?>=? : (%,%) -> Boolean if Character has ORDSET
-\end{verbatim}
-
-<<category SRAGG StringAggregate>>=
-)abbrev category SRAGG StringAggregate
-++ Author: Stephen Watt and Michael Monagan. 
-++ revised by Manuel Bronstein and Richard Jenks
-++ Date Created: August 87 through August 88
-++ Date Last Updated: April 1991
-++ Basic Operations:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ A string aggregate is a category for strings, that is,
-++ one dimensional arrays of characters.
-StringAggregate: Category == OneDimensionalArrayAggregate Character with
-    lowerCase	    : % -> %
-      ++ lowerCase(s) returns the string with all characters in lower case.
-    lowerCase_!: % -> %
-      ++ lowerCase!(s) destructively replaces the alphabetic characters
-      ++ in s by lower case.
-    upperCase	    : % -> %
-      ++ upperCase(s) returns the string with all characters in upper case.
-    upperCase_!: % -> %
-      ++ upperCase!(s) destructively replaces the alphabetic characters
-      ++ in s by upper case characters.
-    prefix?	    : (%, %) -> Boolean
-      ++ prefix?(s,t) tests if the string s is the initial substring of t.
-      ++ Note: \axiom{prefix?(s,t) == 
-      ++   reduce(and,[s.i = t.i for i in 0..maxIndex s])}.
-    suffix?	    : (%, %) -> Boolean
-      ++ suffix?(s,t) tests if the string s is the final substring of t.
-      ++ Note: \axiom{suffix?(s,t) == 
-      ++  reduce(and,[s.i = t.(n - m + i) for i in 0..maxIndex s])}
-      ++ where m and n denote the maxIndex of s and t respectively.
-    substring?: (%, %, Integer) -> Boolean
-      ++ substring?(s,t,i) tests if s is a substring of t beginning at
-      ++ index i.
-      ++ Note: \axiom{substring?(s,t,0) = prefix?(s,t)}.
-    match: (%, %, Character) -> NonNegativeInteger
-      ++ match(p,s,wc) tests if pattern \axiom{p} matches subject \axiom{s}
-      ++ where \axiom{wc} is a wild card character. If no match occurs,
-      ++ the index \axiom{0} is returned; otheriwse, the value returned
-      ++ is the first index of the first character in the subject matching
-      ++ the subject (excluding that matched by an initial wild-card).
-      ++ For example, \axiom{match("*to*","yorktown","*")} returns \axiom{5}
-      ++ indicating a successful match starting at index \axiom{5} of
-      ++ \axiom{"yorktown"}.
-    match?: (%, %, Character) -> Boolean
-      ++ match?(s,t,c) tests if s matches t except perhaps for
-      ++ multiple and consecutive occurrences of character c.
-      ++ Typically c is the blank character.
-    replace	    : (%, UniversalSegment(Integer), %) -> %
-      ++ replace(s,i..j,t) replaces the substring \axiom{s(i..j)} 
-      ++ of s by string t.
-    position	    : (%, %, Integer) -> Integer
-      ++ position(s,t,i) returns the position j of the substring s in 
-      ++ string t, where \axiom{j >= i} is required.
-    position	    : (CharacterClass, %, Integer) -> Integer
-      ++ position(cc,t,i) returns the position \axiom{j >= i} in t of
-      ++ the first character belonging to cc.
-    coerce	    : Character -> %
-      ++ coerce(c) returns c as a string s with the character c.
-    split: (%, Character) -> List %
-      ++ split(s,c) returns a list of substrings delimited by character c.
-    split: (%, CharacterClass) -> List %
-      ++ split(s,cc) returns a list of substrings delimited by 
-      ++ characters in cc.
-    trim: (%, Character) -> %
-      ++ trim(s,c) returns s with all characters c deleted from right
-      ++ and left ends.
-      ++ For example, \axiom{trim(" abc ", char " ")} returns \axiom{"abc"}.
-    trim: (%, CharacterClass) -> %
-      ++ trim(s,cc) returns s with all characters in cc deleted from right
-      ++ and left ends.
-      ++ For example, \axiom{trim("(abc)", charClass "()")} 
-      ++ returns \axiom{"abc"}.
-    leftTrim: (%, Character) -> %
-      ++ leftTrim(s,c) returns s with all leading characters c deleted.
-      ++ For example, \axiom{leftTrim("  abc  ", char " ")} 
-      ++ returns \axiom{"abc  "}.
-    leftTrim: (%, CharacterClass) -> %
-      ++ leftTrim(s,cc) returns s with all leading characters in cc deleted.
-      ++ For example, \axiom{leftTrim("(abc)", charClass "()")} 
-      ++ returns \axiom{"abc)"}.
-    rightTrim: (%, Character) -> %
-      ++ rightTrim(s,c) returns s with all trailing occurrences of c deleted.
-      ++ For example, \axiom{rightTrim("  abc  ", char " ")} 
-      ++ returns \axiom{"  abc"}.
-    rightTrim: (%, CharacterClass) -> %
-      ++ rightTrim(s,cc) returns s with all trailing occurences of
-      ++ characters in cc deleted.
-      ++ For example, \axiom{rightTrim("(abc)", charClass "()")} 
-      ++ returns \axiom{"(abc"}.
-    elt: (%, %) -> %
-      ++ elt(s,t) returns the concatenation of s and t. It is provided to
-      ++ allow juxtaposition of strings to work as concatenation.
-      ++ For example, \axiom{"smoo" "shed"} returns \axiom{"smooshed"}.
- add
-   trim(s: %, c:  Character)	  == leftTrim(rightTrim(s, c),	c)
-   trim(s: %, cc: CharacterClass) == leftTrim(rightTrim(s, cc), cc)
-   lowerCase s		 == lowerCase_! copy s
-   upperCase s		 == upperCase_! copy s
-   prefix?(s, t)	 == substring?(s, t, minIndex t)
-   coerce(c:Character):% == new(1, c)
-   elt(s:%, t:%): %	 == concat(s,t)$%
-
-@
-<<SRAGG.dotabb>>=
-"SRAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=SRAGG"];
-"SRAGG" -> "A1AGG"
-
-@
-<<SRAGG.dotfull>>=
-"StringAggregate()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=SRAGG"];
-"StringAggregate()" -> "OneDimensionalArrayAggregate(Character)"
-
-@
-<<SRAGG.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"StringAggregate()" [color=lightblue];
-"StringAggregate()" -> "OneDimensionalArrayAggregate(Character)"
-
-"OneDimensionalArrayAggregate(Character)" [color=seagreen];
-"OneDimensionalArrayAggregate(Character)" ->
-    "OneDimensionalArrayAggregate(a:Type)"
-
-"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
-"OneDimensionalArrayAggregate(a:Type)" -> 
-    "FiniteLinearAggregate(a:Type)"
-
-"FiniteLinearAggregate(a:Type)" [color=lightblue];
-"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
-
-"LinearAggregate(a:Type)" [color=lightblue];
-"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
-"LinearAggregate(a:Type)" -> "CLAGG..."
-
-"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
-"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
-
-"CLAGG..." [color=lightblue];
-"IXAGG..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{TableAggregate}{TBAGG}
-\pagepic{ps/v102tableaggregate.ps}{TBAGG}{0.60}
-
-{\bf See:}\\
-\pageto{AssociationListAggregate}{ALAGG}
-\pagefrom{IndexedAggregate}{IXAGG}
-\pagefrom{KeyedDictionary}{KDAGG}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{TBAGG}{any?} &
-\cross{TBAGG}{bag} &
-\cross{TBAGG}{coerce} &
-\cross{TBAGG}{construct} &
-\cross{TBAGG}{convert} \\
-\cross{TBAGG}{copy} &
-\cross{TBAGG}{count} &
-\cross{TBAGG}{dictionary} &
-\cross{TBAGG}{elt} &
-\cross{TBAGG}{empty} \\
-\cross{TBAGG}{empty?} &
-\cross{TBAGG}{entries} &
-\cross{TBAGG}{entry?} &
-\cross{TBAGG}{eq?} &
-\cross{TBAGG}{eval} \\
-\cross{TBAGG}{every?} &
-\cross{TBAGG}{extract!} &
-\cross{TBAGG}{fill!} &
-\cross{TBAGG}{find} &
-\cross{TBAGG}{first} \\
-\cross{TBAGG}{hash} &
-\cross{TBAGG}{index?} &
-\cross{TBAGG}{indices} &
-\cross{TBAGG}{insert!} &
-\cross{TBAGG}{inspect} \\
-\cross{TBAGG}{key?} &
-\cross{TBAGG}{keys} &
-\cross{TBAGG}{latex} &
-\cross{TBAGG}{less?} &
-\cross{TBAGG}{map} \\
-\cross{TBAGG}{map!} &
-\cross{TBAGG}{maxIndex} &
-\cross{TBAGG}{member?} &
-\cross{TBAGG}{members} &
-\cross{TBAGG}{minIndex} \\
-\cross{TBAGG}{more?} &
-\cross{TBAGG}{parts} &
-\cross{TBAGG}{qelt} &
-\cross{TBAGG}{qsetelt!} &
-\cross{TBAGG}{reduce} \\
-\cross{TBAGG}{remove} &
-\cross{TBAGG}{remove!} &
-\cross{TBAGG}{removeDuplicates} &
-\cross{TBAGG}{sample} &
-\cross{TBAGG}{search} \\
-\cross{TBAGG}{select} &
-\cross{TBAGG}{select!} &
-\cross{TBAGG}{setelt} &
-\cross{TBAGG}{size?} &
-\cross{TBAGG}{swap!} \\
-\cross{TBAGG}{table} &
-\cross{TBAGG}{\#?} &
-\cross{TBAGG}{?=?} &
-\cross{TBAGG}{?.?} &
-\cross{TBAGG}{?\~{}=?} \\
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item {\bf \cross{TBAGG}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf nil}
-\end{itemize}
-
-{\bf Attributes Used:}
-\begin{itemize}
-\item {\bf \cross{TBAGG}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- setelt : (%,Key,Entry) -> Entry
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- any? : ((Entry -> Boolean),%) -> Boolean 
-     if $ has finiteAggregate
- coerce : % -> OutputForm 
-          if Entry has SETCAT 
-          or Record(key: Key,entry: Entry) has SETCAT
- count : ((Entry -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- elt : (%,Key,Entry) -> Entry         
- entries : % -> List Entry            
- every? : ((Entry -> Boolean),%) -> Boolean 
-         if $ has finiteAggregate
- extract! : % -> Record(key: Key,entry: Entry)
- find : 
-   ((Record(key: Key,entry: Entry) -> Boolean),%)
-      -> Union(Record(key: Key,entry: Entry),"failed")
- index? : (Key,%) -> Boolean          
- indices : % -> List Key
- insert! : (Record(key: Key,entry: Entry),%) -> %
- inspect : % -> Record(key: Key,entry: Entry)
- map : (((Entry,Entry) -> Entry),%,%) -> %
- map : ((Record(key: Key,entry: Entry)
-       -> Record(key: Key,entry: Entry)),%) -> %
- map! : ((Entry -> Entry),%) -> % if $ has shallowlyMutable
- map! : 
-   ((Record(key: Key,entry: Entry)
-       -> Record(key: Key,entry: Entry)),%)
-        -> % if $ has shallowlyMutable
- parts : % -> List Entry if $ has finiteAggregate
- parts : % -> List Record(key: Key,entry: Entry) 
-          if $ has finiteAggregate
- remove! : (Key,%) -> Union(Entry,"failed")
- table : () -> %                      
- table : List Record(key: Key,entry: Entry) -> %
- ?.? : (%,Key) -> Entry
- ?=? : (%,%) -> Boolean 
-          if Entry has SETCAT 
-          or Record(key: Key,entry: Entry) has SETCAT
-\end{verbatim}
-
-These exports come from \refto{KeyedDictionary}(Key,Entry)\\
-where Key:SetCategory and Entry:SetCategory\\
-and RecKE=Record(key: Key,entry: Entry):
-\begin{verbatim}
- any? : ((RecKE -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- bag : List RecKE -> %
- construct : List RecKE -> %
- convert : % -> InputForm if RecKE has KONVERT INFORM
- copy : % -> %                        
- count : (Entry,%) -> NonNegativeInteger 
-          if Entry has SETCAT 
-          and $ has finiteAggregate
- count : ((RecKE -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- dictionary : () -> %
- dictionary : List RecKE -> %
- empty : () -> %                      
- empty? : % -> Boolean
- eq? : (%,%) -> Boolean
- eval : (%,List RecKE,List RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,RecKE,RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,List Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- every? : ((RecKE -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- key? : (Key,%) -> Boolean            
- keys : % -> List Key
- hash : % -> SingleInteger 
-          if Entry has SETCAT 
-          or RecKE has SETCAT
- latex : % -> String 
-          if Entry has SETCAT 
-          or RecKE has SETCAT
- less? : (%,NonNegativeInteger) -> Boolean
- member? : (RecKE,%) -> Boolean 
-     if RecKE has SETCAT 
-      and $ has finiteAggregate
- members : % -> List RecKE if $ has finiteAggregate
- more? : (%,NonNegativeInteger) -> Boolean
- reduce : 
-  (((RecKE,RecKE) -> RecKE),%) -> RecKE 
-          if $ has finiteAggregate
- reduce : 
-  (((RecKE,RecKE)->RecKE),%,RecKE) -> RecKE 
-          if $ has finiteAggregate
- reduce : 
-  (((RecKE,RecKE)->RecKE),%,RecKE,RecKE)
-    -> RecKE 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- remove : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- remove : (RecKE,%) -> % 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- remove! : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- remove! : (RecKE,%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- sample : () -> %                     
- search : (Key,%) -> Union(Entry,"failed")
- select : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- select! : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?~=? : (%,%) -> Boolean 
-          if Entry has SETCAT 
-          or RecKE has SETCAT
-\end{verbatim}
-
-These exports come from \refto{IndexedAggregate}(Key,Entry))\\
-where Key:SetCategory and Entry:SetCategory\\
-and RecKE=Record(key: Key,entry: Entry):
-\begin{verbatim}
- count : (RecKE,%) -> NonNegativeInteger 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- entry? : (Entry,%) -> Boolean 
-          if $ has finiteAggregate 
-          and Entry has SETCAT
- eval : (%,List Equation Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,Equation Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,Entry,Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,List Entry,List Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- fill! : (%,Entry) -> % if $ has shallowlyMutable
- first : % -> Entry if Key has ORDSET
- map : ((Entry -> Entry),%) -> %      
- maxIndex : % -> Key if Key has ORDSET
- member? : (Entry,%) -> Boolean 
-          if Entry has SETCAT 
-          and $ has finiteAggregate
- members : % -> List Entry if $ has finiteAggregate
- minIndex : % -> Key if Key has ORDSET
- qelt : (%,Key) -> Entry
- qsetelt! : (%,Key,Entry) -> Entry if $ has shallowlyMutable
- size? : (%,NonNegativeInteger) -> Boolean
- swap! : (%,Key,Key) -> Void if $ has shallowlyMutable
-\end{verbatim}
-
-<<category TBAGG TableAggregate>>=
-)abbrev category TBAGG TableAggregate
-++ Author: Michael Monagan, Stephen Watt; 
-++ revised by Manuel Bronstein and Richard Jenks
-++ Date Created: August 87 through August 88
-++ Date Last Updated: April 1991
-++ Basic Operations:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ A table aggregate is a model of a table, i.e. a discrete many-to-one
-++ mapping from keys to entries.
-TableAggregate(Key:SetCategory, Entry:SetCategory): Category ==
-  Join(KeyedDictionary(Key,Entry),IndexedAggregate(Key,Entry)) with
-   setelt: (%,Key,Entry) -> Entry	   -- setelt_! later
-     ++ setelt(t,k,e) (also written \axiom{t.k := e}) is equivalent
-     ++ to \axiom{(insert([k,e],t); e)}.
-   table: () -> %
-     ++ table()$T creates an empty table of type T.
-     ++
-     ++E Data:=Record(age:Integer,gender:String)
-     ++E a1:AssociationList(String,Data):=table()
-     ++E a1."tim":=[55,"male"]$Data
-   table: List Record(key:Key,entry:Entry) -> %
-     ++ table([x,y,...,z]) creates a table consisting of entries
-     ++ \axiom{x,y,...,z}.
-   -- to become table: Record(key:Key,entry:Entry)* -> %
-   map: ((Entry, Entry) -> Entry, %, %) -> %
-     ++ map(fn,t1,t2) creates a new table t from given tables t1 and t2 with
-     ++ elements fn(x,y) where x and y are corresponding elements from t1
-     ++ and t2 respectively.
- add
-   table()	       == empty()
-   table l	       == dictionary l
--- empty()	       == dictionary()
-
-   insert_!(p, t)      == (t(p.key) := p.entry; t)
-   indices t	       == keys t
-
-   coerce(t:%):OutputForm ==
-     prefix("table"::OutputForm,
-		    [k::OutputForm = (t.k)::OutputForm for k in keys t])
-
-   elt(t, k) ==
-      (r := search(k, t)) case Entry => r::Entry
-      error "key not in table"
-
-   elt(t, k, e) ==
-      (r := search(k, t)) case Entry => r::Entry
-      e
-
-   map_!(f, t) ==
-      for k in keys t repeat t.k := f t.k
-      t
-
-   map(f:(Entry, Entry) -> Entry, s:%, t:%) ==
-      z := table()
-      for k in keys s | key?(k, t) repeat z.k := f(s.k, t.k)
-      z
-
--- map(f, s, t, x) ==
---    z := table()
---    for k in keys s repeat z.k := f(s.k, t(k, x))
---    for k in keys t | not key?(k, s) repeat z.k := f(t.k, x)
---    z
-
-   if % has finiteAggregate then
-     parts(t:%):List Record(key:Key,entry:Entry) ==
-         [[k, t.k] for k in keys t]
-     parts(t:%):List Entry   == [t.k for k in keys t]
-     entries(t:%):List Entry == parts(t)
-
-     s:% = t:% ==
-       eq?(s,t) => true
-       #s ^= #t => false
-       for k in keys s repeat
-	 (e := search(k, t)) _
-           case "failed" or (e::Entry) ^= s.k => return false
-       true
-
-     map(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%==
-       z := table()
-       for k in keys t repeat
-	 ke: Record(key:Key,entry:Entry) := f [k, t.k]
-	 z ke.key := ke.entry
-       z
-     map_!(f:Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%_
-      ==
-       lke: List Record(key:Key,entry:Entry) := nil()
-       for k in keys t repeat
-	 lke := cons(f [k, remove_!(k,t)::Entry], lke)
-       for ke in lke repeat
-	 t ke.key := ke.entry
-       t
-
-     inspect(t: %): Record(key:Key,entry:Entry) ==
-       ks := keys t
-       empty? ks => error "Cannot extract from an empty aggregate"
-       [first ks, t first ks]
-
-     find(f: Record(key:Key,entry:Entry)->Boolean, t:%):_
-           Union(Record(key:Key,entry:Entry), "failed") ==
-       for ke in parts(t)@List(Record(key:Key,entry:Entry)) _
-          repeat if f ke then return ke
-       "failed"
-
-     index?(k: Key, t: %): Boolean ==
-       search(k,t) case Entry
-
-     remove_!(x:Record(key:Key,entry:Entry), t:%) ==
-       if member?(x, t) then remove_!(x.key, t)
-       t
-     extract_!(t: %): Record(key:Key,entry:Entry) ==
-       k: Record(key:Key,entry:Entry) := inspect t
-       remove_!(k.key, t)
-       k
-
-     any?(f: Entry->Boolean, t: %): Boolean ==
-       for k in keys t | f t k repeat return true
-       false
-     every?(f: Entry->Boolean, t: %): Boolean ==
-       for k in keys t | not f t k repeat return false
-       true
-     count(f: Entry->Boolean, t: %): NonNegativeInteger ==
-       tally: NonNegativeInteger := 0
-       for k in keys t | f t k repeat tally := tally + 1
-       tally
-
-@
-<<TBAGG.dotabb>>=
-"TBAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=TBAGG"];
-"TBAGG" -> "KDAGG"
-"TBAGG" -> "IXAGG"
-
-@
-<<TBAGG.dotfull>>=
-"TableAggregate(a:SetCategory,b:SetCategory)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=TBAGG"];
-"TableAggregate(a:SetCategory,b:SetCategory)" -> 
-    "KeyedDictionary(a:SetCategory,b:SetCategory)"
-"TableAggregate(a:SetCategory,b:SetCategory)" -> 
-    "IndexedAggregate(a:SetCategory,b:SetCategory)"
-
-@
-<<TBAGG.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"TableAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
-"TableAggregate(a:SetCategory,b:SetCategory)" -> 
-    "KeyedDictionary(a:SetCategory,b:SetCategory)"
-"TableAggregate(a:SetCategory,b:SetCategory)" -> 
-    "IndexedAggregate(a:SetCategory,b:SetCategory)"
-
-"IndexedAggregate(a:SetCategory,b:SetCategory)" [color=seagreen];
-"IndexedAggregate(a:SetCategory,b:SetCategory)" ->
-    "IndexedAggregate(a:SetCategory,b:Type)"
-
-"IndexedAggregate(a:SetCategory,b:Type)" [color=lightblue];
-"IndexedAggregate(a:SetCategory,b:Type)" -> "HOAGG..."
-"IndexedAggregate(a:SetCategory,b:Type)" -> "ELTAGG..."
-
-"KeyedDictionary(a:SetCategory,b:SetCategory)" [color=lightblue];
-"KeyedDictionary(a:SetCategory,b:SetCategory)" -> 
-    "Dictionary(Record(a:SetCategory,b:SetCategory))"
-
-"Dictionary(Record(a:SetCategory,b:SetCategory))" [color=seagreen];
-"Dictionary(Record(a:SetCategory,b:SetCategory))" ->
-    "Dictionary(a:SetCategory)"
-
-"Dictionary(a:SetCategory)" [color=lightblue];
-"Dictionary(a:SetCategory)" -> "DictionaryOperations(a:SetCategory)"
-
-"DictionaryOperations(a:SetCategory)" [color=lightblue];
-"DictionaryOperations(a:SetCategory)" -> "BagAggregate(a:SetCategory)"
-"DictionaryOperations(a:SetCategory)" -> "Collection(a:SetCategory)"
-
-"BagAggregate(a:SetCategory)" [color=seagreen];
-"BagAggregate(a:SetCategory)" -> "BagAggregate(a:Type)"
-
-"BagAggregate(a:Type)" [color=lightblue];
-"BagAggregate(a:Type)" -> "HOAGG..."
-
-"Collection(a:SetCategory)" [color=seagreen];
-"Collection(a:SetCategory)" -> "Collection(a:Type)"
-
-"Collection(a:Type)" [color=lightblue];
-"Collection(a:Type)" -> "HOAGG..."
-
-"ELTAGG..." [color=lightblue];
-"HOAGG..." [color=lightblue];
-}
-@
 \chapter{Category Layer 8}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{AssociationListAggregate}{ALAGG}
-\pagepic{ps/v102associationlistaggregate.ps}{ALAGG}{0.45}
-
-{\bf See:}\\
-\pagefrom{ListAggregate}{LSAGG}
-\pagefrom{TableAggregate}{TBAGG}
-
-{\bf Exports:}\\
-\begin{tabular}{llll}
-\cross{ALAGG}{any?} &
-\cross{ALAGG}{assoc} &
-\cross{ALAGG}{bag} &
-\cross{ALAGG}{children} \\
-\cross{ALAGG}{child?} &
-\cross{ALAGG}{coerce} &
-\cross{ALAGG}{concat} &
-\cross{ALAGG}{concat!} \\
-\cross{ALAGG}{construct} &
-\cross{ALAGG}{convert} &
-\cross{ALAGG}{copy} &
-\cross{ALAGG}{copyInto!} \\
-\cross{ALAGG}{count} &
-\cross{ALAGG}{cycleEntry} &
-\cross{ALAGG}{cycleLength} &
-\cross{ALAGG}{cycleSplit!} \\
-\cross{ALAGG}{cycleTail} &
-\cross{ALAGG}{cyclic?} &
-\cross{ALAGG}{delete} &
-\cross{ALAGG}{delete!} \\
-\cross{ALAGG}{dictionary} &
-\cross{ALAGG}{distance} &
-\cross{ALAGG}{elt} &
-\cross{ALAGG}{empty} \\
-\cross{ALAGG}{empty?} &
-\cross{ALAGG}{entries} &
-\cross{ALAGG}{entry?} &
-\cross{ALAGG}{eq?} \\
-\cross{ALAGG}{eval} &
-\cross{ALAGG}{every?} &
-\cross{ALAGG}{explicitlyFinite?} &
-\cross{ALAGG}{extract!} \\
-\cross{ALAGG}{fill!} &
-\cross{ALAGG}{find} &
-\cross{ALAGG}{first} &
-\cross{ALAGG}{hash} \\
-\cross{ALAGG}{index?} &
-\cross{ALAGG}{indices} &
-\cross{ALAGG}{insert} &
-\cross{ALAGG}{insert!} \\
-\cross{ALAGG}{inspect} &
-\cross{ALAGG}{key?} &
-\cross{ALAGG}{keys} &
-\cross{ALAGG}{last} \\
-\cross{ALAGG}{latex} &
-\cross{ALAGG}{leaf?} &
-\cross{ALAGG}{leaves} &
-\cross{ALAGG}{less?} \\
-\cross{ALAGG}{list} &
-\cross{ALAGG}{map} &
-\cross{ALAGG}{map!} &
-\cross{ALAGG}{max} \\
-\cross{ALAGG}{maxIndex} &
-\cross{ALAGG}{member?} &
-\cross{ALAGG}{members} &
-\cross{ALAGG}{merge} \\
-\cross{ALAGG}{merge!} &
-\cross{ALAGG}{min} &
-\cross{ALAGG}{minIndex} &
-\cross{ALAGG}{more?} \\
-\cross{ALAGG}{new} &
-\cross{ALAGG}{nodes} &
-\cross{ALAGG}{node?} &
-\cross{ALAGG}{parts} \\
-\cross{ALAGG}{position} &
-\cross{ALAGG}{possiblyInfinite?} &
-\cross{ALAGG}{qelt} &
-\cross{ALAGG}{qsetelt!} \\
-\cross{ALAGG}{reduce} &
-\cross{ALAGG}{remove} &
-\cross{ALAGG}{remove!} &
-\cross{ALAGG}{removeDuplicates} \\
-\cross{ALAGG}{removeDuplicates!} &
-\cross{ALAGG}{rest} &
-\cross{ALAGG}{reverse} &
-\cross{ALAGG}{reverse!} \\
-\cross{ALAGG}{sample} &
-\cross{ALAGG}{search} &
-\cross{ALAGG}{second} &
-\cross{ALAGG}{select} \\
-\cross{ALAGG}{select!} &
-\cross{ALAGG}{setchildren!} &
-\cross{ALAGG}{setelt} &
-\cross{ALAGG}{setfirst!} \\
-\cross{ALAGG}{setlast!} &
-\cross{ALAGG}{setrest!} &
-\cross{ALAGG}{setvalue!} &
-\cross{ALAGG}{size?} \\
-\cross{ALAGG}{sort} &
-\cross{ALAGG}{sort!} &
-\cross{ALAGG}{sorted?} &
-\cross{ALAGG}{split!} \\
-\cross{ALAGG}{swap!} &
-\cross{ALAGG}{table} &
-\cross{ALAGG}{tail} &
-\cross{ALAGG}{third} \\
-\cross{ALAGG}{value} &
-\cross{ALAGG}{\#?} &
-\cross{ALAGG}{?$<$?} &
-\cross{ALAGG}{?$<=$?} \\
-\cross{ALAGG}{?=?} &
-\cross{ALAGG}{?$>$?} &
-\cross{ALAGG}{?$>=$?} &
-\cross{ALAGG}{?\~{}=?} \\
-\cross{ALAGG}{?.rest} &
-\cross{ALAGG}{?.value} &
-\cross{ALAGG}{?.first} &
-\cross{ALAGG}{?.last} \\
-\cross{ALAGG}{?.?} &
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item {\bf \cross{ALAGG}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf \cross{ALAGG}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf nil}
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- assoc : (Key,%) -> Union(Record(key: Key,entry: Entry),"failed")
-\end{verbatim}
-
-These exports come from \refto{TableAggregate}(Key, Entry)\\
-where Key:SetCategory and Entry:SetCategory\\
-and RecKE = Record(key: Key,entry: Entry)
-\begin{verbatim}
- any? : ((RecKE -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- any? : ((Entry -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- any? : ((RecKE -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- bag : List RecKE -> %
- construct : List RecKE -> %
- convert : % -> InputForm 
-          if RecKE has KONVERT INFORM 
-          or RecKE has KONVERT INFORM
- copy : % -> %                        
- count : 
-  ((RecKE -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- count : (RecKE,%) -> NonNegativeInteger 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- count : ((Entry -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- count : (Entry,%) -> NonNegativeInteger 
-          if Entry has SETCAT 
-          and $ has finiteAggregate
- count : (RecKE,%) -> NonNegativeInteger 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- count : 
-  ((RecKE -> Boolean),%) -> NonNegativeInteger 
-          if $ has finiteAggregate
- dictionary : () -> %                 
- dictionary : List RecKE -> %
- elt : (%,Key,Entry) -> Entry
- elt : (%,Integer,RecKE) -> RecKE
- empty : () -> %
- empty? : % -> Boolean                
- entries : % -> List Entry
- entry? : (Entry,%) -> Boolean 
-          if $ has finiteAggregate 
-          and Entry has SETCAT
- eq? : (%,%) -> Boolean               
- eval : (%,List Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,RecKE,RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,List RecKE,List RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,List Equation Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,Equation Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,Entry,Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,List Entry,List Entry) -> % 
-          if Entry has EVALAB Entry 
-          and Entry has SETCAT
- eval : (%,List RecKE,List RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,RecKE,RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- eval : (%,List Equation RecKE) -> % 
-          if RecKE has EVALAB RecKE 
-          and RecKE has SETCAT
- every? : ((RecKE -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- every? : ((Entry -> Boolean),%) -> Boolean 
-          if $ has finiteAggregate
- extract! : % -> RecKE
- fill! : (%,Entry) -> % if $ has shallowlyMutable
- find : ((RecKE -> Boolean),%) -> Union(RecKE,"failed")
- first : % -> Entry if Key has ORDSET
- hash : % -> SingleInteger 
-          if RecKE has SETCAT 
-          or Entry has SETCAT 
-          or RecKE has SETCAT
- index? : (Key,%) -> Boolean
- indices : % -> List Key
- insert! : (RecKE,%) -> %
- inspect : % -> RecKE
- key? : (Key,%) -> Boolean            
- keys : % -> List Key
- latex : % -> String 
-          if RecKE has SETCAT 
-          or Entry has SETCAT 
-          or RecKE has SETCAT
- less? : (%,NonNegativeInteger) -> Boolean
- map : ((Entry -> Entry),%) -> %
- map : ((RecKE -> RecKE),%) -> %
- map : (((Entry,Entry) -> Entry),%,%) -> %
- map! : ((RecKE -> RecKE),%) -> % 
-          if $ has shallowlyMutable
- map! : ((Entry -> Entry),%) -> % if $ has shallowlyMutable
- map! : ((RecKE -> RecKE),%) -> % 
-          if $ has shallowlyMutable
- maxIndex : % -> Key if Key has ORDSET
- member? : (RecKE,%) -> Boolean 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- member? : (Entry,%) -> Boolean 
-          if Entry has SETCAT 
-          and $ has finiteAggregate
- members : % -> List RecKE if $ has finiteAggregate
- members : % -> List Entry if $ has finiteAggregate
- members : % -> List RecKE if $ has finiteAggregate
- minIndex : % -> Key if Key has ORDSET
- more? : (%,NonNegativeInteger) -> Boolean
- parts : % -> List Entry if $ has finiteAggregate
- parts : % -> List RecKE if $ has finiteAggregate
- qelt : (%,Key) -> Entry              
- qsetelt! : (%,Key,Entry) -> Entry if $ has shallowlyMutable
- reduce : 
-  (((RecKE,RecKE) -> RecKE),%)
-    -> RecKE 
-          if $ has finiteAggregate
- reduce : 
-  (((RecKE,RecKE) -> RecKE),%,RecKE)
-    -> RecKE 
-          if $ has finiteAggregate
- reduce : 
-  (((RecKE,RecKE) -> RecKE),%,RecKE,RecKE)
-    -> RecKE 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- remove : ((RecKE -> Boolean),%) -> % if $ has finiteAggregate
- remove : (RecKE,%) -> % 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate
- remove! : (Key,%) -> Union(Entry,"failed")
- remove! : (RecKE,%) -> % if RecKE has SETCAT
- remove! : (RecKE,%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % 
-          if RecKE has SETCAT 
-          and $ has finiteAggregate 
-          or RecKE has SETCAT 
-          and $ has finiteAggregate
- sample : () -> %
- search : (Key,%) -> Union(Entry,"failed")
- select : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- select! : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- setelt : (%,Key,Entry) -> Entry      
- size? : (%,NonNegativeInteger) -> Boolean
- swap! : (%,Key,Key) -> Void if $ has shallowlyMutable
- table : () -> %
- table : List RecKE -> %
- ?~=? : (%,%) -> Boolean 
-          if RecKE has SETCAT 
-          or Entry has SETCAT 
-          or RecKE has SETCAT
- ?.? : (%,Key) -> Entry               
-\end{verbatim}
-
-These exports come from \refto{ListAggregate}(a)\\
-where a is  Record(key:Key,entry:Entry)\\
-and RecKE=Record(key: Key,entry: Entry)
-\begin{verbatim}
- children : % -> List %               
- child? : (%,%) -> Boolean if RecKE has SETCAT
- coerce : % -> OutputForm 
-          if RecKE has SETCAT 
-          or Entry has SETCAT 
-          or RecKE has SETCAT
- concat : (%,%) -> %
- concat : List % -> %                 
- concat : (RecKE,%) -> %
- concat : (%,RecKE) -> %
- concat! : (%,%) -> %
- concat! : (%,RecKE) -> %
- copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
- cycleEntry : % -> %
- cycleLength : % -> NonNegativeInteger
- cycleSplit! : % -> % if $ has shallowlyMutable
- cycleTail : % -> %                   
- cyclic? : % -> Boolean
- delete : (%,Integer) -> %            
- delete! : (%,Integer) -> %
- delete : (%,UniversalSegment Integer) -> %
- delete! : (%,UniversalSegment Integer) -> %
- distance : (%,%) -> Integer
- entries : % -> List RecKE
- entry? : (RecKE,%) -> Boolean 
-          if $ has finiteAggregate 
-          and RecKE has SETCAT
- explicitlyFinite? : % -> Boolean
- fill! : (%,RecKE) -> % if $ has shallowlyMutable
- first : % -> RecKE
- first : (%,NonNegativeInteger) -> %
- index? : (Integer,%) -> Boolean      
- indices : % -> List Integer          
- insert : (%,%,Integer) -> %          
- insert : (RecKE,%,Integer) -> %
- insert! : (%,%,Integer) -> %
- insert! : (RecKE,%,Integer) -> %
- last : % -> RecKE
- last : (%,NonNegativeInteger) -> %
- leaf? : % -> Boolean                 
- leaves : % -> List RecKE
- list : RecKE -> %
- map : (((RecKE,RecKE) -> RecKE),%,%) -> %
- max : (%,%) -> % if RecKE has ORDSET
- maxIndex : % -> Integer if Integer has ORDSET
- merge : (%,%) -> % if RecKE has ORDSET
- merge : (((RecKE,RecKE) -> Boolean),%,%) -> %
- merge! : (%,%) -> % if RecKE has ORDSET
- merge! : (((RecKE,RecKE) -> Boolean),%,%) -> %
- min : (%,%) -> % if RecKE has ORDSET
- minIndex : % -> Integer if Integer has ORDSET
- new : (NonNegativeInteger,RecKE) -> %
- nodes : % -> List %                  
- node? : (%,%) -> Boolean if RecKE has SETCAT
- position : (RecKE,%,Integer) -> Integer 
-          if RecKE has SETCAT
- position : (RecKE,%) -> Integer 
-          if RecKE has SETCAT
- position : ((RecKE -> Boolean),%) -> Integer
- possiblyInfinite? : % -> Boolean
- qelt : (%,Integer) -> RecKE
- qsetelt! : (%,Integer,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- remove! : ((RecKE -> Boolean),%) -> %
- remove! : ((RecKE -> Boolean),%) -> % 
-          if $ has finiteAggregate
- removeDuplicates! : % -> % if RecKE has SETCAT
- rest : % -> %
- rest : (%,NonNegativeInteger) -> %
- reverse : % -> %                     
- reverse! : % -> % if $ has shallowlyMutable
- second : % -> RecKE
- select! : ((RecKE -> Boolean),%) -> %
- setchildren! : (%,List %) -> % if $ has shallowlyMutable
- setelt : (%,value,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setelt : (%,first,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setelt : (%,rest,%) -> % if $ has shallowlyMutable
- setelt : (%,last,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setelt : (%,UniversalSegment Integer,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setelt : (%,Integer,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setfirst! : (%,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setlast! : (%,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- setrest! : (%,%) -> % if $ has shallowlyMutable
- setvalue! : (%,RecKE) -> RecKE 
-          if $ has shallowlyMutable
- sort : % -> % if RecKE has ORDSET
- sort : (((RecKE,RecKE) -> Boolean),%) -> %
- sort! : % -> % 
-          if RecKE has ORDSET 
-          and $ has shallowlyMutable
- sort! : (((RecKE,RecKE) -> Boolean),%) -> % 
-          if $ has shallowlyMutable
- sorted? : % -> Boolean if RecKE has ORDSET
- sorted? : (((RecKE,RecKE) -> Boolean),%) -> Boolean
- split! : (%,Integer) -> % if $ has shallowlyMutable
- swap! : (%,Integer,Integer) -> Void 
-          if $ has shallowlyMutable
- tail : % -> %                        
- third : % -> RecKE
- value : % -> RecKE
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?<? : (%,%) -> Boolean if RecKE has ORDSET
- ?<=? : (%,%) -> Boolean if RecKE has ORDSET
- ?=? : (%,%) -> Boolean 
-          if RecKE has SETCAT 
-          or Entry has SETCAT 
-          or RecKE has SETCAT
- ?>? : (%,%) -> Boolean if RecKE has ORDSET
- ?>=? : (%,%) -> Boolean if RecKE has ORDSET
- ?.value : (%,value) -> RecKE
- ?.first : (%,first) -> RecKE
- ?.last : (%,last) -> RecKE
- ?.rest : (%,rest) -> %               
- ?.? : (%,UniversalSegment Integer) -> %
- ?.? : (%,Integer) -> RecKE
-\end{verbatim}
-
-<<category ALAGG AssociationListAggregate>>=
-)abbrev category ALAGG AssociationListAggregate
-++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
-++ Date Created: August 87 through August 88
-++ Date Last Updated: April 1991
-++ Basic Operations:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ An association list is a list of key entry pairs which may be viewed
-++ as a table.	It is a poor mans version of a table:
-++ searching for a key is a linear operation.
-AssociationListAggregate(Key:SetCategory,Entry:SetCategory): Category ==
-   Join(TableAggregate(Key, Entry), _
-         ListAggregate Record(key:Key,entry:Entry)) with
-      assoc: (Key, %) -> Union(Record(key:Key,entry:Entry), "failed")
-	++ assoc(k,u) returns the element x in association list u stored
-	++ with key k, or "failed" if u has no key k.
-
-@
-<<ALAGG.dotabb>>=
-"ALAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=ALAGG"];
-"ALAGG" -> "TBAGG"
-"ALAGG" -> "LSAGG"
-
-@
-<<ALAGG.dotfull>>=
-"AssociationListAggregate(a:SetCategory,b:SetCategory)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALAGG"];
-"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
-    "TableAggregate(a:SetCategory,b:SetCategory)"
-"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
-    "ListAggregate(Record(a:SetCategory,b:SetCategory))"
-
-@
-<<ALAGG.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"AssociationListAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
-"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
-    "TableAggregate(a:SetCategory,b:SetCategory)"
-"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
-    "ListAggregate(Record(a:SetCategory,b:SetCategory))"
-
-"TableAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
-"TableAggregate(a:SetCategory,b:SetCategory)" -> "KDAGG..."
-"TableAggregate(a:SetCategory,b:SetCategory)" -> 
-    "IndexedAggregate(a:SetCategory,b:SetCategory)"
-
-"IndexedAggregate(a:SetCategory,b:SetCategory)" [color=seagreen];
-"IndexedAggregate(a:SetCategory,b:SetCategory)" -> "IXAGG..."
-
-"ListAggregate(Record(a:SetCategory,b:SetCategory))" [color=seagreen];
-"ListAggregate(Record(a:SetCategory,b:SetCategory))" -> 
-    "ListAggregate(a:Type)"
-
-"ListAggregate(a:Type)" [color=lightblue];
-"ListAggregate(a:Type)" -> "FiniteLinearAggregate(a:Type)"
-"ListAggregate(a:Type)" -> "ExtensibleLinearAggregate(a:Type)"
-
-"FiniteLinearAggregate(a:Type)" [color=lightblue];
-"FiniteLinearAggregate(a:Type)" -> "LSAGG..."
-
-"ExtensibleLinearAggregate(a:Type)" [color=lightblue];
-"ExtensibleLinearAggregate(a:Type)" -> "LSAGG..."
-
-"KDAGG..." [color=lightblue];
-"IXAGG..." [color=lightblue];
-"LSAGG..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{BiModule}{BMODULE}
 \pagepic{ps/v102bimodule.ps}{BMODULE}{1.00}
 
@@ -22954,6 +22773,7 @@ digraph pic {
 \pageto{MonogenicLinearOperator}{MLO}
 \pageto{RectangularMatrixCategory}{RMATCAT}
 \pageto{SquareMatrixCategory}{SMATCAT}
+\pageto{UnivariateSkewPolynomialCategory}{OREPCAT}
 \pageto{XAlgebra}{XALG}
 \pagefrom{LeftModule}{LMODULE}
 \pagefrom{RightModule}{RMODULE}
@@ -23615,6 +23435,7 @@ digraph pic {
 \pagepic{ps/v102normalizedtriangularsetcategory.ps}{NTSCAT}{0.45}
 
 {\bf See:}\\
+\pageto{SquareFreeNormalizedTriangularSetCategory}{SNTSCAT}
 \pagefrom{RegularTriangularSetCategory}{RSETCAT}
 
 {\bf Exports:}\\
@@ -23900,12 +23721,13 @@ NormalizedTriangularSetCategory(R:GcdDomain,E:OrderedAbelianMonoidSup,_
 @
 <<NTSCAT.dotabb>>=
 "NTSCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NTSCAT"];
 "NTSCAT" -> "RSETCAT"
 
 @
 <<NTSCAT.dotfull>>=
 "NormalizedRegularTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=SFRTCAT"];
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NTSCAT"];
 "NormalizedRegularTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
  ->
 "RegularTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
@@ -24481,6 +24303,7 @@ digraph pic {
 \pageto{MonogenicLinearOperator}{MLO}
 \pageto{OrderedRing}{ORDRING}
 \pageto{PartialDifferentialRing}{PDRING}
+\pageto{UnivariateSkewPolynomialCategory}{OREPCAT}
 \pageto{XAlgebra}{XALG}
 \pageto{XFreeAlgebra}{XFALG}
 \pagefrom{LeftModule}{LMODULE}
@@ -24654,6 +24477,7 @@ digraph pic {
 \pagepic{ps/v102squarefreeregulartriangularsetcategory.ps}{SFRTCAT}{0.50}
 
 {\bf See:}\\
+\pageto{SquareFreeNormalizedTriangularSetCategory}{SNTSCAT}
 \pagefrom{RegularTriangularSetCategory}{RSETCAT}
 
 {\bf Exports:}\\
@@ -24789,8 +24613,8 @@ P:RecursivePolynomialCategory(R,E,V)):
  collectUnder : (%,V) -> %            
  collectUpper : (%,V) -> %
  construct : List P -> %              
- copy : % -> %
  convert : % -> InputForm if P has KONVERT INFORM
+ copy : % -> %
  count : ((P -> Boolean),%) -> NonNegativeInteger 
    if $ has finiteAggregate
  count : (P,%) -> NonNegativeInteger 
@@ -24995,187 +24819,203 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{StringCategory}{STRICAT}
-\pagepic{ps/v102stringcategory.ps}{STRICAT}{0.75}
+\pagehead{StringAggregate}{SRAGG}
+\pagepic{ps/v102stringaggregate.ps}{SRAGG}{1.00}
 
 {\bf See:}\\
-\pagefrom{OpenMath}{OM}
-\pagefrom{SetCategory}{SETCAT}
-\pagefrom{StringAggregate}{SRAGG}
+\pageto{StringCategory}{STRICAT}
+\pagefrom{OneDimensionalArrayAggregate}{A1AGG}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{STRICAT}{any?} &
-\cross{STRICAT}{coerce} &
-\cross{STRICAT}{concat} &
-\cross{STRICAT}{construct} &
-\cross{STRICAT}{convert} \\
-\cross{STRICAT}{copy} &
-\cross{STRICAT}{copyInto!} &
-\cross{STRICAT}{count} &
-\cross{STRICAT}{delete} &
-\cross{STRICAT}{elt} \\
-\cross{STRICAT}{empty} &
-\cross{STRICAT}{empty?} &
-\cross{STRICAT}{entry?} &
-\cross{STRICAT}{entries} &
-\cross{STRICAT}{eq?} \\
-\cross{STRICAT}{eval} &
-\cross{STRICAT}{every?} &
-\cross{STRICAT}{fill!} &
-\cross{STRICAT}{find} &
-\cross{STRICAT}{first} \\
-\cross{STRICAT}{hash} &
-\cross{STRICAT}{index?} &
-\cross{STRICAT}{indices} &
-\cross{STRICAT}{insert} &
-\cross{STRICAT}{latex} \\
-\cross{STRICAT}{leftTrim} &
-\cross{STRICAT}{less?} &
-\cross{STRICAT}{lowerCase} &
-\cross{STRICAT}{lowerCase!} &
-\cross{STRICAT}{map} \\
-\cross{STRICAT}{map!} &
-\cross{STRICAT}{match} &
-\cross{STRICAT}{match?} &
-\cross{STRICAT}{max} &
-\cross{STRICAT}{maxIndex} \\
-\cross{STRICAT}{member?} &
-\cross{STRICAT}{members} &
-\cross{STRICAT}{merge} &
-\cross{STRICAT}{min} &
-\cross{STRICAT}{minIndex} \\
-\cross{STRICAT}{more?} &
-\cross{STRICAT}{new} &
-\cross{STRICAT}{OMwrite} &
-\cross{STRICAT}{parts} &
-\cross{STRICAT}{position} \\
-\cross{STRICAT}{prefix?} &
-\cross{STRICAT}{qelt} &
-\cross{STRICAT}{qsetelt!} &
-\cross{STRICAT}{reduce} &
-\cross{STRICAT}{remove} \\
-\cross{STRICAT}{removeDuplicates} &
-\cross{STRICAT}{replace} &
-\cross{STRICAT}{reverse} &
-\cross{STRICAT}{reverse!} &
-\cross{STRICAT}{rightTrim} \\
-\cross{STRICAT}{sample} &
-\cross{STRICAT}{select} &
-\cross{STRICAT}{setelt} &
-\cross{STRICAT}{size?} &
-\cross{STRICAT}{sort} \\
-\cross{STRICAT}{sort!} &
-\cross{STRICAT}{sorted?} &
-\cross{STRICAT}{sorted?} &
-\cross{STRICAT}{split} &
-\cross{STRICAT}{string} \\
-\cross{STRICAT}{substring?} &
-\cross{STRICAT}{suffix?} &
-\cross{STRICAT}{swap!} &
-\cross{STRICAT}{trim} &
-\cross{STRICAT}{upperCase} \\
-\cross{STRICAT}{upperCase!} &
-\cross{STRICAT}{\#?} &
-\cross{STRICAT}{?$<$?} &
-\cross{STRICAT}{?$<=$?} &
-\cross{STRICAT}{?$>$?} \\
-\cross{STRICAT}{?$>=$?} &
-\cross{STRICAT}{?=?} &
-\cross{STRICAT}{?.?} &
-\cross{STRICAT}{?\~{}=?} &
+\cross{SRAGG}{any?} &
+\cross{SRAGG}{coerce} &
+\cross{SRAGG}{concat} &
+\cross{SRAGG}{construct} &
+\cross{SRAGG}{copy} \\
+\cross{SRAGG}{convert} &
+\cross{SRAGG}{copyInto!} &
+\cross{SRAGG}{count} &
+\cross{SRAGG}{delete} &
+\cross{SRAGG}{?.?} \\
+\cross{SRAGG}{elt} &
+\cross{SRAGG}{empty} &
+\cross{SRAGG}{empty?} &
+\cross{SRAGG}{entries} &
+\cross{SRAGG}{entry?} \\
+\cross{SRAGG}{eval} &
+\cross{SRAGG}{every?} &
+\cross{SRAGG}{eq?} &
+\cross{SRAGG}{fill!} &
+\cross{SRAGG}{find} \\
+\cross{SRAGG}{first} &
+\cross{SRAGG}{hash} &
+\cross{SRAGG}{index?} &
+\cross{SRAGG}{indices} &
+\cross{SRAGG}{insert} \\
+\cross{SRAGG}{latex} &
+\cross{SRAGG}{leftTrim} &
+\cross{SRAGG}{less?} &
+\cross{SRAGG}{lowerCase} &
+\cross{SRAGG}{lowerCase!} \\
+\cross{SRAGG}{map} &
+\cross{SRAGG}{map!} &
+\cross{SRAGG}{match} &
+\cross{SRAGG}{match?} &
+\cross{SRAGG}{max} \\
+\cross{SRAGG}{maxIndex} &
+\cross{SRAGG}{member?} &
+\cross{SRAGG}{members} &
+\cross{SRAGG}{merge} &
+\cross{SRAGG}{min} \\
+\cross{SRAGG}{minIndex} &
+\cross{SRAGG}{more?} &
+\cross{SRAGG}{new} &
+\cross{SRAGG}{parts} &
+\cross{SRAGG}{position} \\
+\cross{SRAGG}{prefix?} &
+\cross{SRAGG}{qelt} &
+\cross{SRAGG}{qsetelt!} &
+\cross{SRAGG}{reduce} &
+\cross{SRAGG}{remove} \\
+\cross{SRAGG}{removeDuplicates} &
+\cross{SRAGG}{replace} &
+\cross{SRAGG}{reverse} &
+\cross{SRAGG}{reverse!} &
+\cross{SRAGG}{rightTrim} \\
+\cross{SRAGG}{sample} &
+\cross{SRAGG}{setelt} &
+\cross{SRAGG}{size?} &
+\cross{SRAGG}{sort} &
+\cross{SRAGG}{sort!} \\
+\cross{SRAGG}{sorted?} &
+\cross{SRAGG}{split} &
+\cross{SRAGG}{substring?} &
+\cross{SRAGG}{suffix?} &
+\cross{SRAGG}{swap!} \\
+\cross{SRAGG}{trim} &
+\cross{SRAGG}{trim} &
+\cross{SRAGG}{upperCase} &
+\cross{SRAGG}{upperCase!} &
+\cross{SRAGG}{\#?} \\
+\cross{SRAGG}{?\~{}=?} &
+\cross{SRAGG}{?.?} &
+\cross{SRAGG}{?$<$?} &
+\cross{SRAGG}{?$<=$?} &
+\cross{SRAGG}{?=?} \\
+\cross{SRAGG}{?$>$?} &
+\cross{SRAGG}{?$>=$?} &&&
 \end{tabular}
 
 {\bf Attributes exported:}
 \begin{itemize}
-\item {\bf \cross{STRICAT}{shallowlyMutable}}
+\item {\bf \cross{SRAGG}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{SRAGG}{shallowlyMutable}}
 is true if its values have immediate components that are 
 updateable (mutable). Note: the properties of any component 
 domain are irrevelant to the shallowlyMutable proper.
-\item {\bf \cross{STRICAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
 \item {\bf nil}
 \end{itemize}
 
 These are directly exported but not implemented:
 \begin{verbatim}
- string : Integer -> %                
+ leftTrim : (%,Character) -> %
+ leftTrim : (%,CharacterClass) -> %
+ lowerCase! : % -> %
+ match : (%,%,Character) -> NonNegativeInteger
+ match? : (%,%,Character) -> Boolean
+ position : (CharacterClass,%,Integer) -> Integer
+ position : (%,%,Integer) -> Integer
+ replace : (%,UniversalSegment Integer,%) -> %
+ rightTrim : (%,Character) -> %
+ rightTrim : (%,CharacterClass) -> %
+ split : (%,Character) -> List %
+ split : (%,CharacterClass) -> List %
+ substring? : (%,%,Integer) -> Boolean
+ suffix? : (%,%) -> Boolean           
+ upperCase! : % -> %                  
 \end{verbatim}
 
-These exports come from \refto{StringAggregate}():
+These are implemented by this category:
 \begin{verbatim}
- any? : ((Character -> Boolean),%) -> Boolean 
-     if $ has finiteAggregate
- coerce : % -> OutputForm
  coerce : Character -> %              
+ lowerCase : % -> %                   
+ prefix? : (%,%) -> Boolean           
+ trim : (%,CharacterClass) -> %
+ trim : (%,Character) -> %            
+ upperCase : % -> %
+ ?.? : (%,%) -> %                     
+\end{verbatim}
+
+These exports come from \refto{OneDimensionalArrayAggregate}(Character):
+\begin{verbatim}
+ any? : ((Character -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ coerce : % -> OutputForm if Character has SETCAT
  concat : List % -> %
  concat : (%,%) -> %                  
  concat : (Character,%) -> %
  concat : (%,Character) -> %          
  construct : List Character -> %
  convert : % -> InputForm 
-     if Character has KONVERT INFORM
+          if Character has KONVERT INFORM
  copy : % -> %                        
  copyInto! : (%,%,Integer) -> % 
-     if $ has shallowlyMutable
+          if $ has shallowlyMutable
  count : (Character,%) -> NonNegativeInteger 
-     if Character has SETCAT 
-     and $ has finiteAggregate
+          if Character has SETCAT 
+          and $ has finiteAggregate
  count : ((Character -> Boolean),%) -> NonNegativeInteger 
-     if $ has finiteAggregate
- delete : (%,UniversalSegment Integer) -> %
+          if $ has finiteAggregate
  delete : (%,Integer) -> %
+ delete : (%,UniversalSegment Integer) -> %
  elt : (%,Integer,Character) -> Character
  empty : () -> %                      
  empty? : % -> Boolean
- entry? : (Character,%) -> Boolean 
-     if $ has finiteAggregate 
-     and Character has SETCAT
  entries : % -> List Character        
+ entry? : (Character,%) -> Boolean 
+          if $ has finiteAggregate 
+          and Character has SETCAT
  eq? : (%,%) -> Boolean
  eval : (%,List Character,List Character) -> % 
-     if Character has EVALAB CHAR 
-     and Character has SETCAT
+          if Character has EVALAB CHAR 
+          and Character has SETCAT
  eval : (%,Character,Character) -> % 
-     if Character has EVALAB CHAR 
-     and Character has SETCAT
+          if Character has EVALAB CHAR 
+          and Character has SETCAT
  eval : (%,Equation Character) -> % 
-     if Character has EVALAB CHAR 
-     and Character has SETCAT
+          if Character has EVALAB CHAR 
+          and Character has SETCAT
  eval : (%,List Equation Character) -> % 
-     if Character has EVALAB CHAR 
-     and Character has SETCAT
+          if Character has EVALAB CHAR 
+          and Character has SETCAT
  every? : ((Character -> Boolean),%) -> Boolean 
-     if $ has finiteAggregate
+          if $ has finiteAggregate
  fill! : (%,Character) -> % 
-     if $ has shallowlyMutable
+          if $ has shallowlyMutable
  find : ((Character -> Boolean),%) -> Union(Character,"failed")
  first : % -> Character 
-     if Integer has ORDSET
- hash : % -> SingleInteger            
- index? : (Integer,%) -> Boolean
- indices : % -> List Integer          
- insert : (%,%,Integer) -> %
+          if Integer has ORDSET
+ hash : % -> SingleInteger 
+          if Character has SETCAT
+ index? : (Integer,%) -> Boolean      
+ indices : % -> List Integer
  insert : (Character,%,Integer) -> %
- latex : % -> String                  
- leftTrim : (%,Character) -> %
- leftTrim : (%,CharacterClass) -> %
+ insert : (%,%,Integer) -> %          
+ latex : % -> String if Character has SETCAT
  less? : (%,NonNegativeInteger) -> Boolean
- lowerCase : % -> %                   
- lowerCase! : % -> %
- map : (((Character,Character) -> Character),%,%) -> %
  map : ((Character -> Character),%) -> %
+ map : (((Character,Character) -> Character),%,%) -> %
  map! : ((Character -> Character),%) -> % 
-     if $ has shallowlyMutable
- match : (%,%,Character) -> NonNegativeInteger
- match? : (%,%,Character) -> Boolean
+          if $ has shallowlyMutable
  max : (%,%) -> % if Character has ORDSET
  maxIndex : % -> Integer if Integer has ORDSET
  member? : (Character,%) -> Boolean 
-     if Character has SETCAT 
-     and $ has finiteAggregate
+          if Character has SETCAT 
+          and $ has finiteAggregate
  members : % -> List Character 
-     if $ has finiteAggregate
+          if $ has finiteAggregate
  merge : (%,%) -> % if Character has ORDSET
  merge : (((Character,Character) -> Boolean),%,%) -> %
  min : (%,%) -> % if Character has ORDSET
@@ -25184,447 +25024,1510 @@ These exports come from \refto{StringAggregate}():
  new : (NonNegativeInteger,Character) -> %
  parts : % -> List Character if $ has finiteAggregate
  position : (Character,%) -> Integer 
-     if Character has SETCAT
+          if Character has SETCAT
  position : ((Character -> Boolean),%) -> Integer
  position : (Character,%,Integer) -> Integer 
-     if Character has SETCAT
- position : (CharacterClass,%,Integer) -> Integer
- position : (%,%,Integer) -> Integer
- prefix? : (%,%) -> Boolean           
+          if Character has SETCAT
  qelt : (%,Integer) -> Character
  qsetelt! : (%,Integer,Character) -> Character 
-     if $ has shallowlyMutable
- reduce : (((Character,Character) -> Character),%)
-    -> Character 
-     if $ has finiteAggregate
- reduce : (((Character,Character) -> Character),%,Character)
-    -> Character 
-     if $ has finiteAggregate
- reduce :
-  (((Character,Character) -> Character),%,Character,Character)
-    -> Character 
-     if Character has SETCAT 
-     and $ has finiteAggregate
+          if $ has shallowlyMutable
+ reduce : (((Character,Character) -> Character),%) -> Character 
+          if $ has finiteAggregate
+ reduce : 
+   (((Character,Character) -> Character),%,Character) -> Character 
+          if $ has finiteAggregate
+ reduce : 
+   (((Character,Character) -> Character),%,Character,Character)
+       -> Character 
+          if Character has SETCAT and $ has finiteAggregate
  remove : ((Character -> Boolean),%) -> % 
-     if $ has finiteAggregate
+          if $ has finiteAggregate
  remove : (Character,%) -> % 
-     if Character has SETCAT 
-     and $ has finiteAggregate
+          if Character has SETCAT 
+          and $ has finiteAggregate
  removeDuplicates : % -> % 
-     if Character has SETCAT 
-     and $ has finiteAggregate
- replace : (%,UniversalSegment Integer,%) -> %
+          if Character has SETCAT 
+          and $ has finiteAggregate
  reverse : % -> %                     
  reverse! : % -> % if $ has shallowlyMutable
- rightTrim : (%,CharacterClass) -> %
- rightTrim : (%,Character) -> %
  sample : () -> %                     
  select : ((Character -> Boolean),%) -> % 
-     if $ has finiteAggregate
- setelt : 
-   (%,UniversalSegment Integer,Character) -> Character 
-     if $ has shallowlyMutable
+          if $ has finiteAggregate
+ setelt : (%,UniversalSegment Integer,Character) -> Character 
+          if $ has shallowlyMutable
+ sort! : (((Character,Character) -> Boolean),%) -> % 
+          if $ has shallowlyMutable
+ sorted? : (((Character,Character) -> Boolean),%) -> Boolean
  setelt : (%,Integer,Character) -> Character 
-     if $ has shallowlyMutable
+          if $ has shallowlyMutable
  size? : (%,NonNegativeInteger) -> Boolean
  sort : % -> % if Character has ORDSET
  sort : (((Character,Character) -> Boolean),%) -> %
  sort! : % -> % 
-     if Character has ORDSET 
-     and $ has shallowlyMutable
- sort! : (((Character,Character) -> Boolean),%) -> % 
-     if $ has shallowlyMutable
- sorted? : (((Character,Character) -> Boolean),%) -> Boolean
+          if Character has ORDSET 
+          and $ has shallowlyMutable
  sorted? : % -> Boolean if Character has ORDSET
- split : (%,CharacterClass) -> List %
- split : (%,Character) -> List %
- substring? : (%,%,Integer) -> Boolean
- suffix? : (%,%) -> Boolean
  swap! : (%,Integer,Integer) -> Void 
-     if $ has shallowlyMutable
- trim : (%,CharacterClass) -> %       
- trim : (%,Character) -> %
- upperCase : % -> %                   
- upperCase! : % -> %
+          if $ has shallowlyMutable
  #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?~=? : (%,%) -> Boolean if Character has SETCAT
+ ?.? : (%,UniversalSegment Integer) -> %
+ ?.? : (%,Integer) -> Character
  ?<? : (%,%) -> Boolean if Character has ORDSET
  ?<=? : (%,%) -> Boolean if Character has ORDSET
+ ?=? : (%,%) -> Boolean if Character has SETCAT
  ?>? : (%,%) -> Boolean if Character has ORDSET
  ?>=? : (%,%) -> Boolean if Character has ORDSET
- ?=? : (%,%) -> Boolean               
- ?~=? : (%,%) -> Boolean              
- ?.? : (%,UniversalSegment Integer) -> %
- ?.? : (%,Integer) -> Character
- ?.? : (%,%) -> %                     
-\end{verbatim}
-
-These exports come from \refto{SetCategory}():
-\begin{verbatim}
-\end{verbatim}
-
-These exports come from \refto{OpenMath}():
-\begin{verbatim}
- OMwrite : (%,Boolean) -> String
- OMwrite : % -> String                
- OMwrite : (OpenMathDevice,%,Boolean) -> Void
- OMwrite : (OpenMathDevice,%) -> Void
 \end{verbatim}
 
-<<category STRICAT StringCategory>>=
-)abbrev category STRICAT StringCategory
--- Note that StringCategory is built into the old compiler
--- redundant SetCategory added to help A# compiler
+<<category SRAGG StringAggregate>>=
+)abbrev category SRAGG StringAggregate
+++ Author: Stephen Watt and Michael Monagan. 
+++ revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
 ++ Description:
-++ A category for string-like objects
-
-StringCategory():Category == _
-     Join(StringAggregate(), SetCategory, OpenMath) with
-  string: Integer -> %
-    ++ string(i) returns the decimal representation of i in a string
+++ A string aggregate is a category for strings, that is,
+++ one dimensional arrays of characters.
+StringAggregate: Category == OneDimensionalArrayAggregate Character with
+    lowerCase	    : % -> %
+      ++ lowerCase(s) returns the string with all characters in lower case.
+    lowerCase_!: % -> %
+      ++ lowerCase!(s) destructively replaces the alphabetic characters
+      ++ in s by lower case.
+    upperCase	    : % -> %
+      ++ upperCase(s) returns the string with all characters in upper case.
+    upperCase_!: % -> %
+      ++ upperCase!(s) destructively replaces the alphabetic characters
+      ++ in s by upper case characters.
+    prefix?	    : (%, %) -> Boolean
+      ++ prefix?(s,t) tests if the string s is the initial substring of t.
+      ++ Note: \axiom{prefix?(s,t) == 
+      ++   reduce(and,[s.i = t.i for i in 0..maxIndex s])}.
+    suffix?	    : (%, %) -> Boolean
+      ++ suffix?(s,t) tests if the string s is the final substring of t.
+      ++ Note: \axiom{suffix?(s,t) == 
+      ++  reduce(and,[s.i = t.(n - m + i) for i in 0..maxIndex s])}
+      ++ where m and n denote the maxIndex of s and t respectively.
+    substring?: (%, %, Integer) -> Boolean
+      ++ substring?(s,t,i) tests if s is a substring of t beginning at
+      ++ index i.
+      ++ Note: \axiom{substring?(s,t,0) = prefix?(s,t)}.
+    match: (%, %, Character) -> NonNegativeInteger
+      ++ match(p,s,wc) tests if pattern \axiom{p} matches subject \axiom{s}
+      ++ where \axiom{wc} is a wild card character. If no match occurs,
+      ++ the index \axiom{0} is returned; otheriwse, the value returned
+      ++ is the first index of the first character in the subject matching
+      ++ the subject (excluding that matched by an initial wild-card).
+      ++ For example, \axiom{match("*to*","yorktown","*")} returns \axiom{5}
+      ++ indicating a successful match starting at index \axiom{5} of
+      ++ \axiom{"yorktown"}.
+    match?: (%, %, Character) -> Boolean
+      ++ match?(s,t,c) tests if s matches t except perhaps for
+      ++ multiple and consecutive occurrences of character c.
+      ++ Typically c is the blank character.
+    replace	    : (%, UniversalSegment(Integer), %) -> %
+      ++ replace(s,i..j,t) replaces the substring \axiom{s(i..j)} 
+      ++ of s by string t.
+    position	    : (%, %, Integer) -> Integer
+      ++ position(s,t,i) returns the position j of the substring s in 
+      ++ string t, where \axiom{j >= i} is required.
+    position	    : (CharacterClass, %, Integer) -> Integer
+      ++ position(cc,t,i) returns the position \axiom{j >= i} in t of
+      ++ the first character belonging to cc.
+    coerce	    : Character -> %
+      ++ coerce(c) returns c as a string s with the character c.
+    split: (%, Character) -> List %
+      ++ split(s,c) returns a list of substrings delimited by character c.
+    split: (%, CharacterClass) -> List %
+      ++ split(s,cc) returns a list of substrings delimited by 
+      ++ characters in cc.
+    trim: (%, Character) -> %
+      ++ trim(s,c) returns s with all characters c deleted from right
+      ++ and left ends.
+      ++ For example, \axiom{trim(" abc ", char " ")} returns \axiom{"abc"}.
+    trim: (%, CharacterClass) -> %
+      ++ trim(s,cc) returns s with all characters in cc deleted from right
+      ++ and left ends.
+      ++ For example, \axiom{trim("(abc)", charClass "()")} 
+      ++ returns \axiom{"abc"}.
+    leftTrim: (%, Character) -> %
+      ++ leftTrim(s,c) returns s with all leading characters c deleted.
+      ++ For example, \axiom{leftTrim("  abc  ", char " ")} 
+      ++ returns \axiom{"abc  "}.
+    leftTrim: (%, CharacterClass) -> %
+      ++ leftTrim(s,cc) returns s with all leading characters in cc deleted.
+      ++ For example, \axiom{leftTrim("(abc)", charClass "()")} 
+      ++ returns \axiom{"abc)"}.
+    rightTrim: (%, Character) -> %
+      ++ rightTrim(s,c) returns s with all trailing occurrences of c deleted.
+      ++ For example, \axiom{rightTrim("  abc  ", char " ")} 
+      ++ returns \axiom{"  abc"}.
+    rightTrim: (%, CharacterClass) -> %
+      ++ rightTrim(s,cc) returns s with all trailing occurences of
+      ++ characters in cc deleted.
+      ++ For example, \axiom{rightTrim("(abc)", charClass "()")} 
+      ++ returns \axiom{"(abc"}.
+    elt: (%, %) -> %
+      ++ elt(s,t) returns the concatenation of s and t. It is provided to
+      ++ allow juxtaposition of strings to work as concatenation.
+      ++ For example, \axiom{"smoo" "shed"} returns \axiom{"smooshed"}.
+ add
+   trim(s: %, c:  Character)	  == leftTrim(rightTrim(s, c),	c)
+   trim(s: %, cc: CharacterClass) == leftTrim(rightTrim(s, cc), cc)
+   lowerCase s		 == lowerCase_! copy s
+   upperCase s		 == upperCase_! copy s
+   prefix?(s, t)	 == substring?(s, t, minIndex t)
+   coerce(c:Character):% == new(1, c)
+   elt(s:%, t:%): %	 == concat(s,t)$%
 
 @
-<<STRICAT.dotabb>>=
-"STRICAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=STRICAT"];
-"STRICAT" -> "OM"
-"STRICAT" -> "SETCAT"
-"STRICAT" -> "SRAGG"
+<<SRAGG.dotabb>>=
+"SRAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=SRAGG"];
+"SRAGG" -> "A1AGG"
 
 @
-<<STRICAT.dotfull>>=
-"StringCategory()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=STRICAT"];
-"StringCategory()" -> "OpenMath()"
-"StringCategory()" -> "SetCategory()"
-"StringCategory()" -> "StringAggregate()"
+<<SRAGG.dotfull>>=
+"StringAggregate()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=SRAGG"];
+"StringAggregate()" -> "OneDimensionalArrayAggregate(Character)"
 
 @
-<<STRICAT.dotpic>>=
+<<SRAGG.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"StringCategory()" [color=lightblue];
-"StringCategory()" -> "OpenMath()"
-"StringCategory()" -> "SetCategory()"
-"StringCategory()" -> "StringAggregate()"
-
-"OpenMath()" [color=lightblue];
-"OpenMath()" -> "Category"
-
-"SetCategory()" [color=lightblue];
-"SetCategory()" -> "BasicType()"
-"SetCategory()" -> "CoercibleTo(OutputForm)"
-
-"BasicType()" [color=lightblue];
-"BasicType()" -> "Category"
+"StringAggregate()" [color=lightblue];
+"StringAggregate()" -> "OneDimensionalArrayAggregate(Character)"
 
-"CoercibleTo(OutputForm)" [color=seagreen];
-"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+"OneDimensionalArrayAggregate(Character)" [color=seagreen];
+"OneDimensionalArrayAggregate(Character)" ->
+    "OneDimensionalArrayAggregate(a:Type)"
 
-"CoercibleTo(a:Type)" [color=lightblue];
-"CoercibleTo(a:Type)" -> "Category"
+"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
+"OneDimensionalArrayAggregate(a:Type)" -> 
+    "FiniteLinearAggregate(a:Type)"
 
-"StringAggregate()" [color=lightblue];
-"StringAggregate()" -> "A1AGG..."
+"FiniteLinearAggregate(a:Type)" [color=lightblue];
+"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
 
-"A1AGG..." [color=lightblue];
+"LinearAggregate(a:Type)" [color=lightblue];
+"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
+"LinearAggregate(a:Type)" -> "CLAGG..."
 
-"Category" [color=lightblue];
+"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
+"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
 
+"CLAGG..." [color=lightblue];
+"IXAGG..." [color=lightblue];
 }
 
 @
-\chapter{Category Layer 9}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{AbelianMonoidRing}{AMR}
-\pagepic{ps/v102abelianmonoidring.ps}{AMR}{0.65}
+\pagehead{TableAggregate}{TBAGG}
+\pagepic{ps/v102tableaggregate.ps}{TBAGG}{0.60}
 
 {\bf See:}\\
-\pageto{FiniteAbelianMonoidRing}{FAMR}
-\pageto{PowerSeriesCategory}{PSCAT}
-\pagefrom{BiModule}{BMODULE}
-\pagefrom{Ring}{RING}
+\pageto{AssociationListAggregate}{ALAGG}
+\pagefrom{IndexedAggregate}{IXAGG}
+\pagefrom{KeyedDictionary}{KDAGG}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{AMR}{0} &
-\cross{AMR}{1} &
-\cross{AMR}{associates?} &
-\cross{AMR}{characteristic} \\
-\cross{AMR}{charthRoot} &
-\cross{AMR}{coefficient} &
-\cross{AMR}{coerce} &
-\cross{AMR}{degree} \\
-\cross{AMR}{exquo} &
-\cross{AMR}{hash} &
-\cross{AMR}{latex} &
-\cross{AMR}{leadingCoefficient} \\
-\cross{AMR}{leadingMonomial} &
-\cross{AMR}{map} &
-\cross{AMR}{monomial} &
-\cross{AMR}{monomial?} \\
-\cross{AMR}{one?} &
-\cross{AMR}{recip} &
-\cross{AMR}{reductum} &
-\cross{AMR}{sample} \\
-\cross{AMR}{subtractIfCan} &
-\cross{AMR}{unit?} &
-\cross{AMR}{unitCanonical} &
-\cross{AMR}{unitNormal} \\
-\cross{AMR}{zero?} &
-\cross{AMR}{?*?} &
-\cross{AMR}{?**?} &
-\cross{AMR}{?+?} \\
-\cross{AMR}{?-?} &
-\cross{AMR}{-?} &
-\cross{AMR}{?=?} &
-\cross{AMR}{?\^{}?} \\
-\cross{AMR}{?\~{}=?} &
-\cross{AMR}{?/?} &&
+\cross{TBAGG}{any?} &
+\cross{TBAGG}{bag} &
+\cross{TBAGG}{coerce} &
+\cross{TBAGG}{construct} &
+\cross{TBAGG}{convert} \\
+\cross{TBAGG}{copy} &
+\cross{TBAGG}{count} &
+\cross{TBAGG}{dictionary} &
+\cross{TBAGG}{elt} &
+\cross{TBAGG}{empty} \\
+\cross{TBAGG}{empty?} &
+\cross{TBAGG}{entries} &
+\cross{TBAGG}{entry?} &
+\cross{TBAGG}{eq?} &
+\cross{TBAGG}{eval} \\
+\cross{TBAGG}{every?} &
+\cross{TBAGG}{extract!} &
+\cross{TBAGG}{fill!} &
+\cross{TBAGG}{find} &
+\cross{TBAGG}{first} \\
+\cross{TBAGG}{hash} &
+\cross{TBAGG}{index?} &
+\cross{TBAGG}{indices} &
+\cross{TBAGG}{insert!} &
+\cross{TBAGG}{inspect} \\
+\cross{TBAGG}{key?} &
+\cross{TBAGG}{keys} &
+\cross{TBAGG}{latex} &
+\cross{TBAGG}{less?} &
+\cross{TBAGG}{map} \\
+\cross{TBAGG}{map!} &
+\cross{TBAGG}{maxIndex} &
+\cross{TBAGG}{member?} &
+\cross{TBAGG}{members} &
+\cross{TBAGG}{minIndex} \\
+\cross{TBAGG}{more?} &
+\cross{TBAGG}{parts} &
+\cross{TBAGG}{qelt} &
+\cross{TBAGG}{qsetelt!} &
+\cross{TBAGG}{reduce} \\
+\cross{TBAGG}{remove} &
+\cross{TBAGG}{remove!} &
+\cross{TBAGG}{removeDuplicates} &
+\cross{TBAGG}{sample} &
+\cross{TBAGG}{search} \\
+\cross{TBAGG}{select} &
+\cross{TBAGG}{select!} &
+\cross{TBAGG}{setelt} &
+\cross{TBAGG}{size?} &
+\cross{TBAGG}{swap!} \\
+\cross{TBAGG}{table} &
+\cross{TBAGG}{\#?} &
+\cross{TBAGG}{?=?} &
+\cross{TBAGG}{?.?} &
+\cross{TBAGG}{?\~{}=?} \\
 \end{tabular}
 
 {\bf Attributes exported:}
 \begin{itemize}
-\item if \$ has CommutativeRing then commutative(``*'') where
-{\bf \cross{AMR}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
-\item if \$ has IntegralDomain then noZeroDivisors where
-{\bf \cross{AMR}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item {\bf \cross{AMR}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{AMR}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{AMR}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
+\item {\bf \cross{TBAGG}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf nil}
+\end{itemize}
+
+{\bf Attributes Used:}
+\begin{itemize}
+\item {\bf \cross{TBAGG}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
 \end{itemize}
 
 These are directly exported but not implemented:
 \begin{verbatim}
- coefficient : (%,E) -> R
- degree : % -> E                      
- leadingCoefficient : % -> R
- leadingMonomial : % -> %             
- monomial : (R,E) -> %                
- reductum : % -> %                    
- ?/? : (%,R) -> % if R has FIELD
+ setelt : (%,Key,Entry) -> Entry
 \end{verbatim}
 
 These are implemented by this category:
 \begin{verbatim}
- map : ((R -> R),%) -> %
- monomial? : % -> Boolean
- ?*? : (Fraction Integer,%) -> % if R has ALGEBRA FRAC INT
+ any? : ((Entry -> Boolean),%) -> Boolean 
+     if $ has finiteAggregate
+ coerce : % -> OutputForm 
+          if Entry has SETCAT 
+          or Record(key: Key,entry: Entry) has SETCAT
+ count : ((Entry -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ elt : (%,Key,Entry) -> Entry         
+ entries : % -> List Entry            
+ every? : ((Entry -> Boolean),%) -> Boolean 
+         if $ has finiteAggregate
+ extract! : % -> Record(key: Key,entry: Entry)
+ find : 
+   ((Record(key: Key,entry: Entry) -> Boolean),%)
+      -> Union(Record(key: Key,entry: Entry),"failed")
+ index? : (Key,%) -> Boolean          
+ indices : % -> List Key
+ insert! : (Record(key: Key,entry: Entry),%) -> %
+ inspect : % -> Record(key: Key,entry: Entry)
+ map : (((Entry,Entry) -> Entry),%,%) -> %
+ map : ((Record(key: Key,entry: Entry)
+       -> Record(key: Key,entry: Entry)),%) -> %
+ map! : ((Entry -> Entry),%) -> % if $ has shallowlyMutable
+ map! : 
+   ((Record(key: Key,entry: Entry)
+       -> Record(key: Key,entry: Entry)),%)
+        -> % if $ has shallowlyMutable
+ parts : % -> List Entry if $ has finiteAggregate
+ parts : % -> List Record(key: Key,entry: Entry) 
+          if $ has finiteAggregate
+ remove! : (Key,%) -> Union(Entry,"failed")
+ table : () -> %                      
+ table : List Record(key: Key,entry: Entry) -> %
+ ?.? : (%,Key) -> Entry
+ ?=? : (%,%) -> Boolean 
+          if Entry has SETCAT 
+          or Record(key: Key,entry: Entry) has SETCAT
 \end{verbatim}
 
-These exports come from \refto{Ring}():
+These exports come from \refto{KeyedDictionary}(Key,Entry)\\
+where Key:SetCategory and Entry:SetCategory\\
+and RecKE=Record(key: Key,entry: Entry):
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- characteristic : () -> NonNegativeInteger
- coerce : % -> OutputForm
- coerce : Integer -> %                
- hash : % -> SingleInteger
- latex : % -> String                  
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean                 
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (Integer,%) -> %
- ?*? : (%,%) -> %                     
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
+ any? : ((RecKE -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ bag : List RecKE -> %
+ construct : List RecKE -> %
+ convert : % -> InputForm if RecKE has KONVERT INFORM
+ copy : % -> %                        
+ count : (Entry,%) -> NonNegativeInteger 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ count : ((RecKE -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ dictionary : () -> %
+ dictionary : List RecKE -> %
+ empty : () -> %                      
+ empty? : % -> Boolean
+ eq? : (%,%) -> Boolean
+ eval : (%,List RecKE,List RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,RecKE,RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,List Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ every? : ((RecKE -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ key? : (Key,%) -> Boolean            
+ keys : % -> List Key
+ hash : % -> SingleInteger 
+          if Entry has SETCAT 
+          or RecKE has SETCAT
+ latex : % -> String 
+          if Entry has SETCAT 
+          or RecKE has SETCAT
+ less? : (%,NonNegativeInteger) -> Boolean
+ member? : (RecKE,%) -> Boolean 
+     if RecKE has SETCAT 
+      and $ has finiteAggregate
+ members : % -> List RecKE if $ has finiteAggregate
+ more? : (%,NonNegativeInteger) -> Boolean
+ reduce : 
+  (((RecKE,RecKE) -> RecKE),%) -> RecKE 
+          if $ has finiteAggregate
+ reduce : 
+  (((RecKE,RecKE)->RecKE),%,RecKE) -> RecKE 
+          if $ has finiteAggregate
+ reduce : 
+  (((RecKE,RecKE)->RecKE),%,RecKE,RecKE)
+    -> RecKE 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ remove : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ remove : (RecKE,%) -> % 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ remove! : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ remove! : (RecKE,%) -> % if $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ sample : () -> %                     
+ search : (Key,%) -> Union(Entry,"failed")
+ select : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ select! : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?~=? : (%,%) -> Boolean 
+          if Entry has SETCAT 
+          or RecKE has SETCAT
 \end{verbatim}
 
-These exports come from \refto{BiModule}(R:Ring,R:Ring):
+These exports come from \refto{IndexedAggregate}(Key,Entry))\\
+where Key:SetCategory and Entry:SetCategory\\
+and RecKE=Record(key: Key,entry: Entry):
 \begin{verbatim}
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
+ count : (RecKE,%) -> NonNegativeInteger 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ entry? : (Entry,%) -> Boolean 
+          if $ has finiteAggregate 
+          and Entry has SETCAT
+ eval : (%,List Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Entry,Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List Entry,List Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ fill! : (%,Entry) -> % if $ has shallowlyMutable
+ first : % -> Entry if Key has ORDSET
+ map : ((Entry -> Entry),%) -> %      
+ maxIndex : % -> Key if Key has ORDSET
+ member? : (Entry,%) -> Boolean 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ members : % -> List Entry if $ has finiteAggregate
+ minIndex : % -> Key if Key has ORDSET
+ qelt : (%,Key) -> Entry
+ qsetelt! : (%,Key,Entry) -> Entry if $ has shallowlyMutable
+ size? : (%,NonNegativeInteger) -> Boolean
+ swap! : (%,Key,Key) -> Void if $ has shallowlyMutable
 \end{verbatim}
 
-These exports come from \refto{IntegralDomain}():
-\begin{verbatim}
- associates? : (%,%) -> Boolean if R has INTDOM
- coerce : % -> % if R has INTDOM
- exquo : (%,%) -> Union(%,"failed") if R has INTDOM
- unit? : % -> Boolean if R has INTDOM
- unitCanonical : % -> % if R has INTDOM
- unitNormal : % -> Record(unit: %,canonical: %,associate: %) if R has INTDOM
-\end{verbatim}
+<<category TBAGG TableAggregate>>=
+)abbrev category TBAGG TableAggregate
+++ Author: Michael Monagan, Stephen Watt; 
+++ revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A table aggregate is a model of a table, i.e. a discrete many-to-one
+++ mapping from keys to entries.
+TableAggregate(Key:SetCategory, Entry:SetCategory): Category ==
+  Join(KeyedDictionary(Key,Entry),IndexedAggregate(Key,Entry)) with
+   setelt: (%,Key,Entry) -> Entry	   -- setelt_! later
+     ++ setelt(t,k,e) (also written \axiom{t.k := e}) is equivalent
+     ++ to \axiom{(insert([k,e],t); e)}.
+   table: () -> %
+     ++ table()$T creates an empty table of type T.
+     ++
+     ++E Data:=Record(age:Integer,gender:String)
+     ++E a1:AssociationList(String,Data):=table()
+     ++E a1."tim":=[55,"male"]$Data
+   table: List Record(key:Key,entry:Entry) -> %
+     ++ table([x,y,...,z]) creates a table consisting of entries
+     ++ \axiom{x,y,...,z}.
+   -- to become table: Record(key:Key,entry:Entry)* -> %
+   map: ((Entry, Entry) -> Entry, %, %) -> %
+     ++ map(fn,t1,t2) creates a new table t from given tables t1 and t2 with
+     ++ elements fn(x,y) where x and y are corresponding elements from t1
+     ++ and t2 respectively.
+ add
+   table()	       == empty()
+   table l	       == dictionary l
+-- empty()	       == dictionary()
 
-These exports come from \refto{CharacteristicNonZero}():
-\begin{verbatim}
- charthRoot : % -> Union(%,"failed") if R has CHARNZ
-\end{verbatim}
+   insert_!(p, t)      == (t(p.key) := p.entry; t)
+   indices t	       == keys t
 
-These exports come from \refto{CommutativeRing}():
+   coerce(t:%):OutputForm ==
+     prefix("table"::OutputForm,
+		    [k::OutputForm = (t.k)::OutputForm for k in keys t])
+
+   elt(t, k) ==
+      (r := search(k, t)) case Entry => r::Entry
+      error "key not in table"
+
+   elt(t, k, e) ==
+      (r := search(k, t)) case Entry => r::Entry
+      e
+
+   map_!(f, t) ==
+      for k in keys t repeat t.k := f t.k
+      t
+
+   map(f:(Entry, Entry) -> Entry, s:%, t:%) ==
+      z := table()
+      for k in keys s | key?(k, t) repeat z.k := f(s.k, t.k)
+      z
+
+-- map(f, s, t, x) ==
+--    z := table()
+--    for k in keys s repeat z.k := f(s.k, t(k, x))
+--    for k in keys t | not key?(k, s) repeat z.k := f(t.k, x)
+--    z
+
+   if % has finiteAggregate then
+     parts(t:%):List Record(key:Key,entry:Entry) ==
+         [[k, t.k] for k in keys t]
+     parts(t:%):List Entry   == [t.k for k in keys t]
+     entries(t:%):List Entry == parts(t)
+
+     s:% = t:% ==
+       eq?(s,t) => true
+       #s ^= #t => false
+       for k in keys s repeat
+	 (e := search(k, t)) _
+           case "failed" or (e::Entry) ^= s.k => return false
+       true
+
+     map(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%==
+       z := table()
+       for k in keys t repeat
+	 ke: Record(key:Key,entry:Entry) := f [k, t.k]
+	 z ke.key := ke.entry
+       z
+     map_!(f:Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%_
+      ==
+       lke: List Record(key:Key,entry:Entry) := nil()
+       for k in keys t repeat
+	 lke := cons(f [k, remove_!(k,t)::Entry], lke)
+       for ke in lke repeat
+	 t ke.key := ke.entry
+       t
+
+     inspect(t: %): Record(key:Key,entry:Entry) ==
+       ks := keys t
+       empty? ks => error "Cannot extract from an empty aggregate"
+       [first ks, t first ks]
+
+     find(f: Record(key:Key,entry:Entry)->Boolean, t:%):_
+           Union(Record(key:Key,entry:Entry), "failed") ==
+       for ke in parts(t)@List(Record(key:Key,entry:Entry)) _
+          repeat if f ke then return ke
+       "failed"
+
+     index?(k: Key, t: %): Boolean ==
+       search(k,t) case Entry
+
+     remove_!(x:Record(key:Key,entry:Entry), t:%) ==
+       if member?(x, t) then remove_!(x.key, t)
+       t
+     extract_!(t: %): Record(key:Key,entry:Entry) ==
+       k: Record(key:Key,entry:Entry) := inspect t
+       remove_!(k.key, t)
+       k
+
+     any?(f: Entry->Boolean, t: %): Boolean ==
+       for k in keys t | f t k repeat return true
+       false
+     every?(f: Entry->Boolean, t: %): Boolean ==
+       for k in keys t | not f t k repeat return false
+       true
+     count(f: Entry->Boolean, t: %): NonNegativeInteger ==
+       tally: NonNegativeInteger := 0
+       for k in keys t | f t k repeat tally := tally + 1
+       tally
+
+@
+<<TBAGG.dotabb>>=
+"TBAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=TBAGG"];
+"TBAGG" -> "KDAGG"
+"TBAGG" -> "IXAGG"
+
+@
+<<TBAGG.dotfull>>=
+"TableAggregate(a:SetCategory,b:SetCategory)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=TBAGG"];
+"TableAggregate(a:SetCategory,b:SetCategory)" -> 
+    "KeyedDictionary(a:SetCategory,b:SetCategory)"
+"TableAggregate(a:SetCategory,b:SetCategory)" -> 
+    "IndexedAggregate(a:SetCategory,b:SetCategory)"
+
+@
+<<TBAGG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"TableAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
+"TableAggregate(a:SetCategory,b:SetCategory)" -> 
+    "KeyedDictionary(a:SetCategory,b:SetCategory)"
+"TableAggregate(a:SetCategory,b:SetCategory)" -> 
+    "IndexedAggregate(a:SetCategory,b:SetCategory)"
+
+"IndexedAggregate(a:SetCategory,b:SetCategory)" [color=seagreen];
+"IndexedAggregate(a:SetCategory,b:SetCategory)" ->
+    "IndexedAggregate(a:SetCategory,b:Type)"
+
+"IndexedAggregate(a:SetCategory,b:Type)" [color=lightblue];
+"IndexedAggregate(a:SetCategory,b:Type)" -> "HOAGG..."
+"IndexedAggregate(a:SetCategory,b:Type)" -> "ELTAGG..."
+
+"KeyedDictionary(a:SetCategory,b:SetCategory)" [color=lightblue];
+"KeyedDictionary(a:SetCategory,b:SetCategory)" -> 
+    "Dictionary(Record(a:SetCategory,b:SetCategory))"
+
+"Dictionary(Record(a:SetCategory,b:SetCategory))" [color=seagreen];
+"Dictionary(Record(a:SetCategory,b:SetCategory))" ->
+    "Dictionary(a:SetCategory)"
+
+"Dictionary(a:SetCategory)" [color=lightblue];
+"Dictionary(a:SetCategory)" -> "DictionaryOperations(a:SetCategory)"
+
+"DictionaryOperations(a:SetCategory)" [color=lightblue];
+"DictionaryOperations(a:SetCategory)" -> "BagAggregate(a:SetCategory)"
+"DictionaryOperations(a:SetCategory)" -> "Collection(a:SetCategory)"
+
+"BagAggregate(a:SetCategory)" [color=seagreen];
+"BagAggregate(a:SetCategory)" -> "BagAggregate(a:Type)"
+
+"BagAggregate(a:Type)" [color=lightblue];
+"BagAggregate(a:Type)" -> "HOAGG..."
+
+"Collection(a:SetCategory)" [color=seagreen];
+"Collection(a:SetCategory)" -> "Collection(a:Type)"
+
+"Collection(a:Type)" [color=lightblue];
+"Collection(a:Type)" -> "HOAGG..."
+
+"ELTAGG..." [color=lightblue];
+"HOAGG..." [color=lightblue];
+}
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{VectorCategory}{VECTCAT}
+\pagepic{ps/v102vectorcategory.ps}{VECTCAT}{1.00}
+
+{\bf See:}\\
+\pageto{PointCategory}{PTCAT}
+\pagefrom{OneDimensionalArrayAggregate}{A1AGG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{VECTCAT}{any?} &
+\cross{VECTCAT}{coerce} &
+\cross{VECTCAT}{concat} &
+\cross{VECTCAT}{construct} &
+\cross{VECTCAT}{convert} \\
+\cross{VECTCAT}{copy} &
+\cross{VECTCAT}{copyInto!} &
+\cross{VECTCAT}{count} &
+\cross{VECTCAT}{cross} &
+\cross{VECTCAT}{delete} \\
+\cross{VECTCAT}{dot} &
+\cross{VECTCAT}{entry?} &
+\cross{VECTCAT}{elt} &
+\cross{VECTCAT}{empty} &
+\cross{VECTCAT}{empty?} \\
+\cross{VECTCAT}{entries} &
+\cross{VECTCAT}{eq?} &
+\cross{VECTCAT}{eval} &
+\cross{VECTCAT}{every?} &
+\cross{VECTCAT}{fill!} \\
+\cross{VECTCAT}{find} &
+\cross{VECTCAT}{first} &
+\cross{VECTCAT}{hash} &
+\cross{VECTCAT}{index?} &
+\cross{VECTCAT}{indices} \\
+\cross{VECTCAT}{insert} &
+\cross{VECTCAT}{latex} &
+\cross{VECTCAT}{length} &
+\cross{VECTCAT}{less?} &
+\cross{VECTCAT}{magnitude} \\
+\cross{VECTCAT}{map} &
+\cross{VECTCAT}{map!} &
+\cross{VECTCAT}{max} &
+\cross{VECTCAT}{maxIndex} &
+\cross{VECTCAT}{member?} \\
+\cross{VECTCAT}{members} &
+\cross{VECTCAT}{merge} &
+\cross{VECTCAT}{min} &
+\cross{VECTCAT}{minIndex} &
+\cross{VECTCAT}{more?} \\
+\cross{VECTCAT}{new} &
+\cross{VECTCAT}{outerProduct} &
+\cross{VECTCAT}{parts} &
+\cross{VECTCAT}{position} &
+\cross{VECTCAT}{qelt} \\
+\cross{VECTCAT}{qsetelt!} &
+\cross{VECTCAT}{reduce} &
+\cross{VECTCAT}{remove} &
+\cross{VECTCAT}{removeDuplicates} &
+\cross{VECTCAT}{reverse} \\
+\cross{VECTCAT}{reverse!} &
+\cross{VECTCAT}{sample} &
+\cross{VECTCAT}{select} &
+\cross{VECTCAT}{setelt} &
+\cross{VECTCAT}{size?} \\
+\cross{VECTCAT}{sort} &
+\cross{VECTCAT}{sort!} &
+\cross{VECTCAT}{sorted?} &
+\cross{VECTCAT}{swap!} &
+\cross{VECTCAT}{zero} \\
+\cross{VECTCAT}{\#?} &
+\cross{VECTCAT}{?*?} &
+\cross{VECTCAT}{?+?} &
+\cross{VECTCAT}{?-?} &
+\cross{VECTCAT}{?$<$?} \\
+\cross{VECTCAT}{?$<=$?} &
+\cross{VECTCAT}{?=?} &
+\cross{VECTCAT}{?$>$?} &
+\cross{VECTCAT}{?$>=$?} &
+\cross{VECTCAT}{-?} \\
+\cross{VECTCAT}{?.?} &
+\cross{VECTCAT}{?\~{}=?} &&&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{VECTCAT}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf \cross{VECTCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\end{itemize}
+
+These are implemented by this category:
 \begin{verbatim}
- coerce : R -> % if R has COMRING
+ cross : (%,%) -> % if R has RING
+ dot : (%,%) -> R if R has RING
+ length : % -> R if R has RING and R has RADCAT
+ magnitude : % -> R if R has RING and R has RADCAT
+ outerProduct : (%,%) -> Matrix R if R has RING
+ zero : NonNegativeInteger -> % if R has ABELMON
+ ?*? : (Integer,%) -> % if R has ABELGRP
+ ?*? : (%,R) -> % if R has MONOID
+ ?*? : (R,%) -> % if R has MONOID
+ ?-? : (%,%) -> % if R has ABELGRP
+ -? : % -> % if R has ABELGRP         
+ ?+? : (%,%) -> % if R has ABELSG
 \end{verbatim}
 
-These exports come from \refto{Algebra}(Fraction(Integer)):
+These exports come from \refto{OneDimensionalArrayAggregate}(R:Type):
 \begin{verbatim}
- coerce : Fraction Integer -> % if R has ALGEBRA FRAC INT
- ?*? : (%,Fraction Integer) -> % if R has ALGEBRA FRAC INT
+ any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ coerce : % -> OutputForm if R has SETCAT
+ concat : (R,%) -> %
+ concat : (%,R) -> %                  
+ concat : List % -> %
+ concat : (%,%) -> %                  
+ construct : List R -> %
+ convert : % -> InputForm if R has KONVERT INFORM
+ copy : % -> %                        
+ copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ delete : (%,Integer) -> %
+ delete : (%,UniversalSegment Integer) -> %
+ elt : (%,Integer,R) -> R
+ empty : () -> %                      
+ empty? : % -> Boolean
+ entries : % -> List R                
+ entry? : (R,%) -> Boolean if $ has finiteAggregate and R has SETCAT
+ eq? : (%,%) -> Boolean
+ eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ fill! : (%,R) -> % if $ has shallowlyMutable
+ find : ((R -> Boolean),%) -> Union(R,"failed")
+ first : % -> R if Integer has ORDSET
+ hash : % -> SingleInteger if R has SETCAT
+ index? : (Integer,%) -> Boolean      
+ indices : % -> List Integer
+ insert : (%,%,Integer) -> %          
+ insert : (R,%,Integer) -> %
+ latex : % -> String if R has SETCAT
+ less? : (%,NonNegativeInteger) -> Boolean
+ map : ((R -> R),%) -> %
+ map : (((R,R) -> R),%,%) -> %        
+ map! : ((R -> R),%) -> % if $ has shallowlyMutable
+ max : (%,%) -> % if R has ORDSET
+ maxIndex : % -> Integer if Integer has ORDSET
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ members : % -> List R if $ has finiteAggregate
+ merge : (%,%) -> % if R has ORDSET
+ merge : (((R,R) -> Boolean),%,%) -> %
+ min : (%,%) -> % if R has ORDSET
+ minIndex : % -> Integer if Integer has ORDSET
+ more? : (%,NonNegativeInteger) -> Boolean
+ new : (NonNegativeInteger,R) -> %    
+ parts : % -> List R if $ has finiteAggregate
+ position : (R,%) -> Integer if R has SETCAT
+ position : ((R -> Boolean),%) -> Integer
+ position : (R,%,Integer) -> Integer if R has SETCAT
+ qelt : (%,Integer) -> R
+ qsetelt! : (%,Integer,R) -> R if $ has shallowlyMutable
+ reduce : (((R,R) -> R),%) -> R if $ has finiteAggregate
+ reduce : (((R,R) -> R),%,R) -> R if $ has finiteAggregate
+ reduce : (((R,R) -> R),%,R,R) -> R if R has SETCAT and $ has finiteAggregate
+ remove : ((R -> Boolean),%) -> % if $ has finiteAggregate
+ remove : (R,%) -> % if R has SETCAT and $ has finiteAggregate
+ removeDuplicates : % -> % if R has SETCAT and $ has finiteAggregate
+ reverse : % -> %                     
+ reverse! : % -> % if $ has shallowlyMutable
+ sample : () -> %
+ select : ((R -> Boolean),%) -> % if $ has finiteAggregate
+ setelt : (%,Integer,R) -> R if $ has shallowlyMutable
+ setelt : (%,UniversalSegment Integer,R) -> R if $ has shallowlyMutable
+ size? : (%,NonNegativeInteger) -> Boolean
+ sort : % -> % if R has ORDSET
+ sort : (((R,R) -> Boolean),%) -> %
+ sort! : % -> % if R has ORDSET and $ has shallowlyMutable
+ sort! : (((R,R) -> Boolean),%) -> % if $ has shallowlyMutable
+ sorted? : % -> Boolean if R has ORDSET
+ sorted? : (((R,R) -> Boolean),%) -> Boolean
+ swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?.? : (%,Integer) -> R               
+ ?.? : (%,UniversalSegment Integer) -> %
+ ?=? : (%,%) -> Boolean if R has SETCAT
+ ?<? : (%,%) -> Boolean if R has ORDSET
+ ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?>? : (%,%) -> Boolean if R has ORDSET
+ ?>=? : (%,%) -> Boolean if R has ORDSET
+ ?~=? : (%,%) -> Boolean if R has SETCAT
 \end{verbatim}
 
-<<category AMR AbelianMonoidRing>>=
-)abbrev category AMR AbelianMonoidRing
+<<category VECTCAT VectorCategory>>=
+)abbrev category VECTCAT VectorCategory
 ++ Author:
 ++ Date Created:
 ++ Date Last Updated:
 ++ Basic Functions:
-++ Related Constructors:
+++ Related Constructors: DirectProductCategory, Vector, IndexedVector
 ++ Also See:
 ++ AMS Classifications:
 ++ Keywords:
 ++ References:
 ++ Description:
-++ Abelian monoid ring elements (not necessarily of finite support)
-++ of this ring are of the form formal SUM (r_i * e_i)
-++ where the r_i are coefficents and the e_i, elements of the
-++ ordered abelian monoid, are thought of as exponents or monomials.
-++ The monomials commute with each other, and with
-++ the coefficients (which themselves may or may not be commutative).
-++ See \spadtype{FiniteAbelianMonoidRing} for the case of finite support
-++ a useful common model for polynomials and power series.
-++ Conceptually at least, only the non-zero terms are ever operated on.
-AbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
-     Join(Ring,BiModule(R,R)) with
-  leadingCoefficient: % -> R
-    ++ leadingCoefficient(p) returns the coefficient highest 
-    ++ degree term of p.
-  leadingMonomial: % -> %
-    ++ leadingMonomial(p) returns the monomial of p with the highest degree.
-  degree: % -> E
-    ++ degree(p) returns the maximum of the exponents of the terms of p.
-  map: (R -> R, %) -> %
-    ++ map(fn,u) maps function fn onto the coefficients
-    ++ of the non-zero monomials of u.
-  monomial?: % -> Boolean
-    ++ monomial?(p) tests if p is a single monomial.
-  monomial: (R,E) -> %
-    ++ monomial(r,e) makes a term from a coefficient r and an exponent e.
-  reductum: % -> %
-    ++ reductum(u) returns u minus its leading monomial
-    ++ returns zero if handed the zero element.
-  coefficient: (%,E) -> R
-    ++ coefficient(p,e) extracts the coefficient of the monomial with
-    ++ exponent e from polynomial p, or returns zero if exponent 
-    ++ is not present.
-  if R has Field then "/": (%,R) -> %
-    ++ p/c divides p by the coefficient c.
-  if R has CommutativeRing then
-     CommutativeRing
-     Algebra R
-  if R has CharacteristicZero then CharacteristicZero
-  if R has CharacteristicNonZero then CharacteristicNonZero
-  if R has IntegralDomain then IntegralDomain
-  if R has Algebra Fraction Integer then Algebra Fraction Integer
+++ \spadtype{VectorCategory} represents the type of vector like objects,
+++ i.e. finite sequences indexed by some finite segment of the
+++ integers. The operations available on vectors depend on the structure
+++ of the underlying components. Many operations from the component domain
+++ are defined for vectors componentwise. It can by assumed that extraction or
+++ updating components can be done in constant time.
+ 
+VectorCategory(R:Type): Category == OneDimensionalArrayAggregate R with
+    if R has AbelianSemiGroup then
+      _+ : (%, %) -> %
+        ++ x + y returns the component-wise sum of the vectors x and y.
+        ++ Error: if x and y are not of the same length.
+    if R has AbelianMonoid then
+      zero: NonNegativeInteger -> %
+        ++ zero(n) creates a zero vector of length n.
+    if R has AbelianGroup then
+      _- : % -> %
+        ++ -x negates all components of the vector x.
+      _- : (%, %) -> %
+        ++ x - y returns the component-wise difference of the vectors x and y.
+        ++ Error: if x and y are not of the same length.
+      _* : (Integer, %) -> %
+        ++ n * y multiplies each component of the vector y by the integer n.
+    if R has Monoid then
+      _* : (R, %) -> %
+        ++ r * y multiplies the element r times each component of the vector y.
+      _* : (%, R) -> %
+        ++ y * r multiplies each component of the vector y by the element r.
+    if R has Ring then
+      dot: (%, %) -> R
+        ++ dot(x,y) computes the inner product of the two vectors x and y.
+        ++ Error: if x and y are not of the same length.
+      outerProduct: (%, %) -> Matrix R
+        ++ outerProduct(u,v) constructs the matrix whose (i,j)'th element is
+        ++ u(i)*v(j).
+      cross: (%, %) -> %
+        ++ vectorProduct(u,v) constructs the cross product of u and v.
+        ++ Error: if u and v are not of length 3.
+    if R has RadicalCategory and R has Ring then
+      length: % -> R
+        ++ length(v) computes the sqrt(dot(v,v)), i.e. the magnitude
+      magnitude: % -> R
+        ++ magnitude(v) computes the sqrt(dot(v,v)), i.e. the length
  add
-  monomial? x == zero? reductum x
+    if R has AbelianSemiGroup then
+      u + v ==
+        (n := #u) ^= #v => error "Vectors must be of the same length"
+        map(_+ , u, v)
+ 
+    if R has AbelianMonoid then
+      zero n == new(n, 0)
+ 
+    if R has AbelianGroup then
+      - u             == map(- #1, u)
 
-  map(fn:R -> R, x: %) ==
-        -- this default definition assumes that reductum is cheap
-     zero? x => 0
-     r:=fn leadingCoefficient x
-     zero? r => map(fn,reductum x)
-     monomial(r, degree x) + map(fn,reductum x)
+      n:Integer * u:% == map(n * #1, u)
 
-  if R has Algebra Fraction Integer then
-    q:Fraction(Integer) * p:% == map(q * #1, p)
+      u - v           == u + (-v)
+ 
+    if R has Monoid then
+      u:% * r:R       == map(#1 * r, u)
+
+      r:R * u:%       == map(r * #1, u)
+ 
+    if R has Ring then
+      dot(u, v) ==
+        #u ^= #v => error "Vectors must be of the same length"
+        _+/[qelt(u, i) * qelt(v, i) for i in minIndex u .. maxIndex u]
 
+      outerProduct(u, v) ==
+        matrix [[qelt(u, i) * qelt(v,j) for i in minIndex u .. maxIndex u] _
+                for j in minIndex v .. maxIndex v]
+
+      cross(u, v) ==
+        #u ^= 3 or #v ^= 3 => error "Vectors must be of length 3"
+        construct [qelt(u, 2)*qelt(v, 3) - qelt(u, 3)*qelt(v, 2) , _
+                   qelt(u, 3)*qelt(v, 1) - qelt(u, 1)*qelt(v, 3) , _
+                   qelt(u, 1)*qelt(v, 2) - qelt(u, 2)*qelt(v, 1) ]
+
+    if R has RadicalCategory and R has Ring then
+      length p ==
+         sqrt(dot(p,p))
+
+      magnitude p ==
+         sqrt(dot(p,p))
+ 
 @
-<<AMR.dotabb>>=
-"AMR"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=AMR"];
-"AMR" -> "RING"
-"AMR" -> "BMODULE"
-"AMR" -> "INTDOM"
-"AMR" -> "CHARNZ"
-"AMR" -> "COMRING"
-"AMR" -> "ALGEBRA"
+<<VECTCAT.dotabb>>=
+"VECTCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=VECTCAT"];
+"VECTCAT" -> "A1AGG"
 
 @
-<<AMR.dotfull>>=
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=AMR"];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "Ring()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BiModule(a:Ring,b:OrderedAbelianMonoid)"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
+<<VECTCAT.dotfull>>=
+"VectorCategory(a:Type)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=VECTCAT"];
+"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
+
+"VectorCategory(a:Ring)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=VECTCAT"];
+"VectorCategory(a:Ring)" -> "VectorCategory(a:Type)"
 
 @
-<<AMR.dotpic>>=
+<<VECTCAT.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BIMODULE..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
+"VectorCategory(a:Type)" [color=lightblue];
+"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
 
-"IntegralDomain()" [color=lightblue];
-"IntegralDomain()" -> "CommutativeRing()"
-"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
-"IntegralDomain()" -> "EntireRing()"
+"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
+"OneDimensionalArrayAggregate(a:Type)" -> 
+    "FiniteLinearAggregate(a:Type)"
 
-"EntireRing()" [color=lightblue];
-"EntireRing()" -> "RING..."
-"EntireRing()" -> "BIMODULE..."
+"FiniteLinearAggregate(a:Type)" [color=lightblue];
+"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
 
-"CharacteristicNonZero()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
-"CharacteristicNonZero()" -> "RING..."
+"LinearAggregate(a:Type)" [color=lightblue];
+"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
+"LinearAggregate(a:Type)" -> "CLAGG..."
 
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
+"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
 
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "RING..."
-"Algebra(a:CommutativeRing)" -> "MODULE..."
+"CLAGG..." [color=lightblue];
+"IXAGG..." [color=lightblue];
+}
 
-"CommutativeRing()" [color=lightblue];
-"CommutativeRing()" -> "RING..."
-"CommutativeRing()" -> "BIMODULE..."
+@
+\chapter{Category Layer 9}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{AssociationListAggregate}{ALAGG}
+\pagepic{ps/v102associationlistaggregate.ps}{ALAGG}{0.45}
 
-"BIMODULE..." [color=lightblue];
-"RING..." [color=lightblue];
-"MODULE..." [color=lightblue];
+{\bf See:}\\
+\pagefrom{ListAggregate}{LSAGG}
+\pagefrom{TableAggregate}{TBAGG}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{ALAGG}{any?} &
+\cross{ALAGG}{assoc} &
+\cross{ALAGG}{bag} &
+\cross{ALAGG}{children} \\
+\cross{ALAGG}{child?} &
+\cross{ALAGG}{coerce} &
+\cross{ALAGG}{concat} &
+\cross{ALAGG}{concat!} \\
+\cross{ALAGG}{construct} &
+\cross{ALAGG}{convert} &
+\cross{ALAGG}{copy} &
+\cross{ALAGG}{copyInto!} \\
+\cross{ALAGG}{count} &
+\cross{ALAGG}{cycleEntry} &
+\cross{ALAGG}{cycleLength} &
+\cross{ALAGG}{cycleSplit!} \\
+\cross{ALAGG}{cycleTail} &
+\cross{ALAGG}{cyclic?} &
+\cross{ALAGG}{delete} &
+\cross{ALAGG}{delete!} \\
+\cross{ALAGG}{dictionary} &
+\cross{ALAGG}{distance} &
+\cross{ALAGG}{elt} &
+\cross{ALAGG}{empty} \\
+\cross{ALAGG}{empty?} &
+\cross{ALAGG}{entries} &
+\cross{ALAGG}{entry?} &
+\cross{ALAGG}{eq?} \\
+\cross{ALAGG}{eval} &
+\cross{ALAGG}{every?} &
+\cross{ALAGG}{explicitlyFinite?} &
+\cross{ALAGG}{extract!} \\
+\cross{ALAGG}{fill!} &
+\cross{ALAGG}{find} &
+\cross{ALAGG}{first} &
+\cross{ALAGG}{hash} \\
+\cross{ALAGG}{index?} &
+\cross{ALAGG}{indices} &
+\cross{ALAGG}{insert} &
+\cross{ALAGG}{insert!} \\
+\cross{ALAGG}{inspect} &
+\cross{ALAGG}{key?} &
+\cross{ALAGG}{keys} &
+\cross{ALAGG}{last} \\
+\cross{ALAGG}{latex} &
+\cross{ALAGG}{leaf?} &
+\cross{ALAGG}{leaves} &
+\cross{ALAGG}{less?} \\
+\cross{ALAGG}{list} &
+\cross{ALAGG}{map} &
+\cross{ALAGG}{map!} &
+\cross{ALAGG}{max} \\
+\cross{ALAGG}{maxIndex} &
+\cross{ALAGG}{member?} &
+\cross{ALAGG}{members} &
+\cross{ALAGG}{merge} \\
+\cross{ALAGG}{merge!} &
+\cross{ALAGG}{min} &
+\cross{ALAGG}{minIndex} &
+\cross{ALAGG}{more?} \\
+\cross{ALAGG}{new} &
+\cross{ALAGG}{nodes} &
+\cross{ALAGG}{node?} &
+\cross{ALAGG}{parts} \\
+\cross{ALAGG}{position} &
+\cross{ALAGG}{possiblyInfinite?} &
+\cross{ALAGG}{qelt} &
+\cross{ALAGG}{qsetelt!} \\
+\cross{ALAGG}{reduce} &
+\cross{ALAGG}{remove} &
+\cross{ALAGG}{remove!} &
+\cross{ALAGG}{removeDuplicates} \\
+\cross{ALAGG}{removeDuplicates!} &
+\cross{ALAGG}{rest} &
+\cross{ALAGG}{reverse} &
+\cross{ALAGG}{reverse!} \\
+\cross{ALAGG}{sample} &
+\cross{ALAGG}{search} &
+\cross{ALAGG}{second} &
+\cross{ALAGG}{select} \\
+\cross{ALAGG}{select!} &
+\cross{ALAGG}{setchildren!} &
+\cross{ALAGG}{setelt} &
+\cross{ALAGG}{setfirst!} \\
+\cross{ALAGG}{setlast!} &
+\cross{ALAGG}{setrest!} &
+\cross{ALAGG}{setvalue!} &
+\cross{ALAGG}{size?} \\
+\cross{ALAGG}{sort} &
+\cross{ALAGG}{sort!} &
+\cross{ALAGG}{sorted?} &
+\cross{ALAGG}{split!} \\
+\cross{ALAGG}{swap!} &
+\cross{ALAGG}{table} &
+\cross{ALAGG}{tail} &
+\cross{ALAGG}{third} \\
+\cross{ALAGG}{value} &
+\cross{ALAGG}{\#?} &
+\cross{ALAGG}{?$<$?} &
+\cross{ALAGG}{?$<=$?} \\
+\cross{ALAGG}{?=?} &
+\cross{ALAGG}{?$>$?} &
+\cross{ALAGG}{?$>=$?} &
+\cross{ALAGG}{?\~{}=?} \\
+\cross{ALAGG}{?.rest} &
+\cross{ALAGG}{?.value} &
+\cross{ALAGG}{?.first} &
+\cross{ALAGG}{?.last} \\
+\cross{ALAGG}{?.?} &
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item {\bf \cross{ALAGG}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf \cross{ALAGG}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf nil}
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ assoc : (Key,%) -> Union(Record(key: Key,entry: Entry),"failed")
+\end{verbatim}
+
+These exports come from \refto{TableAggregate}(Key, Entry)\\
+where Key:SetCategory and Entry:SetCategory\\
+and RecKE = Record(key: Key,entry: Entry)
+\begin{verbatim}
+ any? : ((RecKE -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ any? : ((Entry -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ any? : ((RecKE -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ bag : List RecKE -> %
+ construct : List RecKE -> %
+ convert : % -> InputForm 
+          if RecKE has KONVERT INFORM 
+          or RecKE has KONVERT INFORM
+ copy : % -> %                        
+ count : 
+  ((RecKE -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ count : (RecKE,%) -> NonNegativeInteger 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ count : ((Entry -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ count : (Entry,%) -> NonNegativeInteger 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ count : (RecKE,%) -> NonNegativeInteger 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ count : 
+  ((RecKE -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ dictionary : () -> %                 
+ dictionary : List RecKE -> %
+ elt : (%,Key,Entry) -> Entry
+ elt : (%,Integer,RecKE) -> RecKE
+ empty : () -> %
+ empty? : % -> Boolean                
+ entries : % -> List Entry
+ entry? : (Entry,%) -> Boolean 
+          if $ has finiteAggregate 
+          and Entry has SETCAT
+ eq? : (%,%) -> Boolean               
+ eval : (%,List Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,RecKE,RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,List RecKE,List RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,List Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Entry,Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List Entry,List Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List RecKE,List RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,RecKE,RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ eval : (%,List Equation RecKE) -> % 
+          if RecKE has EVALAB RecKE 
+          and RecKE has SETCAT
+ every? : ((RecKE -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ every? : ((Entry -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ extract! : % -> RecKE
+ fill! : (%,Entry) -> % if $ has shallowlyMutable
+ find : ((RecKE -> Boolean),%) -> Union(RecKE,"failed")
+ first : % -> Entry if Key has ORDSET
+ hash : % -> SingleInteger 
+          if RecKE has SETCAT 
+          or Entry has SETCAT 
+          or RecKE has SETCAT
+ index? : (Key,%) -> Boolean
+ indices : % -> List Key
+ insert! : (RecKE,%) -> %
+ inspect : % -> RecKE
+ key? : (Key,%) -> Boolean            
+ keys : % -> List Key
+ latex : % -> String 
+          if RecKE has SETCAT 
+          or Entry has SETCAT 
+          or RecKE has SETCAT
+ less? : (%,NonNegativeInteger) -> Boolean
+ map : ((Entry -> Entry),%) -> %
+ map : ((RecKE -> RecKE),%) -> %
+ map : (((Entry,Entry) -> Entry),%,%) -> %
+ map! : ((RecKE -> RecKE),%) -> % 
+          if $ has shallowlyMutable
+ map! : ((Entry -> Entry),%) -> % if $ has shallowlyMutable
+ map! : ((RecKE -> RecKE),%) -> % 
+          if $ has shallowlyMutable
+ maxIndex : % -> Key if Key has ORDSET
+ member? : (RecKE,%) -> Boolean 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ member? : (Entry,%) -> Boolean 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ members : % -> List RecKE if $ has finiteAggregate
+ members : % -> List Entry if $ has finiteAggregate
+ members : % -> List RecKE if $ has finiteAggregate
+ minIndex : % -> Key if Key has ORDSET
+ more? : (%,NonNegativeInteger) -> Boolean
+ parts : % -> List Entry if $ has finiteAggregate
+ parts : % -> List RecKE if $ has finiteAggregate
+ qelt : (%,Key) -> Entry              
+ qsetelt! : (%,Key,Entry) -> Entry if $ has shallowlyMutable
+ reduce : 
+  (((RecKE,RecKE) -> RecKE),%)
+    -> RecKE 
+          if $ has finiteAggregate
+ reduce : 
+  (((RecKE,RecKE) -> RecKE),%,RecKE)
+    -> RecKE 
+          if $ has finiteAggregate
+ reduce : 
+  (((RecKE,RecKE) -> RecKE),%,RecKE,RecKE)
+    -> RecKE 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ remove : ((RecKE -> Boolean),%) -> % if $ has finiteAggregate
+ remove : (RecKE,%) -> % 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate
+ remove! : (Key,%) -> Union(Entry,"failed")
+ remove! : (RecKE,%) -> % if RecKE has SETCAT
+ remove! : (RecKE,%) -> % if $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if RecKE has SETCAT 
+          and $ has finiteAggregate 
+          or RecKE has SETCAT 
+          and $ has finiteAggregate
+ sample : () -> %
+ search : (Key,%) -> Union(Entry,"failed")
+ select : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ select! : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ setelt : (%,Key,Entry) -> Entry      
+ size? : (%,NonNegativeInteger) -> Boolean
+ swap! : (%,Key,Key) -> Void if $ has shallowlyMutable
+ table : () -> %
+ table : List RecKE -> %
+ ?~=? : (%,%) -> Boolean 
+          if RecKE has SETCAT 
+          or Entry has SETCAT 
+          or RecKE has SETCAT
+ ?.? : (%,Key) -> Entry               
+\end{verbatim}
+
+These exports come from \refto{ListAggregate}(a)\\
+where a is  Record(key:Key,entry:Entry)\\
+and RecKE=Record(key: Key,entry: Entry)
+\begin{verbatim}
+ children : % -> List %               
+ child? : (%,%) -> Boolean if RecKE has SETCAT
+ coerce : % -> OutputForm 
+          if RecKE has SETCAT 
+          or Entry has SETCAT 
+          or RecKE has SETCAT
+ concat : (%,%) -> %
+ concat : List % -> %                 
+ concat : (RecKE,%) -> %
+ concat : (%,RecKE) -> %
+ concat! : (%,%) -> %
+ concat! : (%,RecKE) -> %
+ copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
+ cycleEntry : % -> %
+ cycleLength : % -> NonNegativeInteger
+ cycleSplit! : % -> % if $ has shallowlyMutable
+ cycleTail : % -> %                   
+ cyclic? : % -> Boolean
+ delete : (%,Integer) -> %            
+ delete! : (%,Integer) -> %
+ delete : (%,UniversalSegment Integer) -> %
+ delete! : (%,UniversalSegment Integer) -> %
+ distance : (%,%) -> Integer
+ entries : % -> List RecKE
+ entry? : (RecKE,%) -> Boolean 
+          if $ has finiteAggregate 
+          and RecKE has SETCAT
+ explicitlyFinite? : % -> Boolean
+ fill! : (%,RecKE) -> % if $ has shallowlyMutable
+ first : % -> RecKE
+ first : (%,NonNegativeInteger) -> %
+ index? : (Integer,%) -> Boolean      
+ indices : % -> List Integer          
+ insert : (%,%,Integer) -> %          
+ insert : (RecKE,%,Integer) -> %
+ insert! : (%,%,Integer) -> %
+ insert! : (RecKE,%,Integer) -> %
+ last : % -> RecKE
+ last : (%,NonNegativeInteger) -> %
+ leaf? : % -> Boolean                 
+ leaves : % -> List RecKE
+ list : RecKE -> %
+ map : (((RecKE,RecKE) -> RecKE),%,%) -> %
+ max : (%,%) -> % if RecKE has ORDSET
+ maxIndex : % -> Integer if Integer has ORDSET
+ merge : (%,%) -> % if RecKE has ORDSET
+ merge : (((RecKE,RecKE) -> Boolean),%,%) -> %
+ merge! : (%,%) -> % if RecKE has ORDSET
+ merge! : (((RecKE,RecKE) -> Boolean),%,%) -> %
+ min : (%,%) -> % if RecKE has ORDSET
+ minIndex : % -> Integer if Integer has ORDSET
+ new : (NonNegativeInteger,RecKE) -> %
+ nodes : % -> List %                  
+ node? : (%,%) -> Boolean if RecKE has SETCAT
+ position : (RecKE,%,Integer) -> Integer 
+          if RecKE has SETCAT
+ position : (RecKE,%) -> Integer 
+          if RecKE has SETCAT
+ position : ((RecKE -> Boolean),%) -> Integer
+ possiblyInfinite? : % -> Boolean
+ qelt : (%,Integer) -> RecKE
+ qsetelt! : (%,Integer,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ remove! : ((RecKE -> Boolean),%) -> %
+ remove! : ((RecKE -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ removeDuplicates! : % -> % if RecKE has SETCAT
+ rest : % -> %
+ rest : (%,NonNegativeInteger) -> %
+ reverse : % -> %                     
+ reverse! : % -> % if $ has shallowlyMutable
+ second : % -> RecKE
+ select! : ((RecKE -> Boolean),%) -> %
+ setchildren! : (%,List %) -> % if $ has shallowlyMutable
+ setelt : (%,value,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setelt : (%,first,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setelt : (%,rest,%) -> % if $ has shallowlyMutable
+ setelt : (%,last,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setelt : (%,UniversalSegment Integer,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setelt : (%,Integer,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setfirst! : (%,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setlast! : (%,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ setrest! : (%,%) -> % if $ has shallowlyMutable
+ setvalue! : (%,RecKE) -> RecKE 
+          if $ has shallowlyMutable
+ sort : % -> % if RecKE has ORDSET
+ sort : (((RecKE,RecKE) -> Boolean),%) -> %
+ sort! : % -> % 
+          if RecKE has ORDSET 
+          and $ has shallowlyMutable
+ sort! : (((RecKE,RecKE) -> Boolean),%) -> % 
+          if $ has shallowlyMutable
+ sorted? : % -> Boolean if RecKE has ORDSET
+ sorted? : (((RecKE,RecKE) -> Boolean),%) -> Boolean
+ split! : (%,Integer) -> % if $ has shallowlyMutable
+ swap! : (%,Integer,Integer) -> Void 
+          if $ has shallowlyMutable
+ tail : % -> %                        
+ third : % -> RecKE
+ value : % -> RecKE
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?<? : (%,%) -> Boolean if RecKE has ORDSET
+ ?<=? : (%,%) -> Boolean if RecKE has ORDSET
+ ?=? : (%,%) -> Boolean 
+          if RecKE has SETCAT 
+          or Entry has SETCAT 
+          or RecKE has SETCAT
+ ?>? : (%,%) -> Boolean if RecKE has ORDSET
+ ?>=? : (%,%) -> Boolean if RecKE has ORDSET
+ ?.value : (%,value) -> RecKE
+ ?.first : (%,first) -> RecKE
+ ?.last : (%,last) -> RecKE
+ ?.rest : (%,rest) -> %               
+ ?.? : (%,UniversalSegment Integer) -> %
+ ?.? : (%,Integer) -> RecKE
+\end{verbatim}
+
+<<category ALAGG AssociationListAggregate>>=
+)abbrev category ALAGG AssociationListAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An association list is a list of key entry pairs which may be viewed
+++ as a table.	It is a poor mans version of a table:
+++ searching for a key is a linear operation.
+AssociationListAggregate(Key:SetCategory,Entry:SetCategory): Category ==
+   Join(TableAggregate(Key, Entry), _
+         ListAggregate Record(key:Key,entry:Entry)) with
+      assoc: (Key, %) -> Union(Record(key:Key,entry:Entry), "failed")
+	++ assoc(k,u) returns the element x in association list u stored
+	++ with key k, or "failed" if u has no key k.
+
+@
+<<ALAGG.dotabb>>=
+"ALAGG" [color=lightblue,href="bookvol10.2.pdf#nameddest=ALAGG"];
+"ALAGG" -> "TBAGG"
+"ALAGG" -> "LSAGG"
+
+@
+<<ALAGG.dotfull>>=
+"AssociationListAggregate(a:SetCategory,b:SetCategory)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALAGG"];
+"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
+    "TableAggregate(a:SetCategory,b:SetCategory)"
+"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
+    "ListAggregate(Record(a:SetCategory,b:SetCategory))"
+
+@
+<<ALAGG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"AssociationListAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
+"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
+    "TableAggregate(a:SetCategory,b:SetCategory)"
+"AssociationListAggregate(a:SetCategory,b:SetCategory)" ->
+    "ListAggregate(Record(a:SetCategory,b:SetCategory))"
+
+"TableAggregate(a:SetCategory,b:SetCategory)" [color=lightblue];
+"TableAggregate(a:SetCategory,b:SetCategory)" -> "KDAGG..."
+"TableAggregate(a:SetCategory,b:SetCategory)" -> 
+    "IndexedAggregate(a:SetCategory,b:SetCategory)"
+
+"IndexedAggregate(a:SetCategory,b:SetCategory)" [color=seagreen];
+"IndexedAggregate(a:SetCategory,b:SetCategory)" -> "IXAGG..."
+
+"ListAggregate(Record(a:SetCategory,b:SetCategory))" [color=seagreen];
+"ListAggregate(Record(a:SetCategory,b:SetCategory))" -> 
+    "ListAggregate(a:Type)"
+
+"ListAggregate(a:Type)" [color=lightblue];
+"ListAggregate(a:Type)" -> "FiniteLinearAggregate(a:Type)"
+"ListAggregate(a:Type)" -> "ExtensibleLinearAggregate(a:Type)"
+
+"FiniteLinearAggregate(a:Type)" [color=lightblue];
+"FiniteLinearAggregate(a:Type)" -> "LSAGG..."
+
+"ExtensibleLinearAggregate(a:Type)" [color=lightblue];
+"ExtensibleLinearAggregate(a:Type)" -> "LSAGG..."
+
+"KDAGG..." [color=lightblue];
+"IXAGG..." [color=lightblue];
+"LSAGG..." [color=lightblue];
 }
 
 @
@@ -25788,6 +26691,7 @@ digraph pic {
 \pageto{IntegerNumberSystem}{INS}
 \pageto{PAdicIntegerCategory}{PADICCT}
 \pageto{QuotientFieldCategory}{QFCAT}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{RealNumberSystem}{RNS}
 \pagefrom{Ring}{RING}
 
@@ -25926,9 +26830,11 @@ digraph pic {
 \pagepic{ps/v102commutativering.ps}{COMRING}{0.65}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{IntegralDomain}{INTDOM}
 \pageto{FunctionSpace}{FS}
 \pageto{MonogenicAlgebra}{MONOGEN}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{UnivariatePolynomialCategory}{UPOLYC}
 \pagefrom{BiModule}{BMODULE}
 \pagefrom{Ring}{RING}
@@ -26000,9 +26906,6 @@ These exports come from \refto{Ring}():
  ?**? : (%,PositiveInteger) -> %
 \end{verbatim}
 
-TPDHERE: Note that none of the exports of BiModule(a:Ring,b:Ring)
-are needed. Perhaps this can be eliminated. 
-
 <<category COMRING CommutativeRing>>=
 )abbrev category COMRING CommutativeRing
 ++ Author:
@@ -26345,9 +27248,6 @@ These exports come from \refto{Ring}():
  ?**? : (%,PositiveInteger) -> %
 \end{verbatim}
 
-TPDHERE: Note that none of the exports of BiModule(a:Ring,b:Ring)
-are needed. Perhaps this can be eliminated. 
-
 <<category ENTIRER EntireRing>>=
 )abbrev category ENTIRER EntireRing
 ++ Author:
@@ -26953,12 +27853,149 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{Module}{MODULE}
+\pagepic{ps/v102module.ps}{MODULE}{1.00}
+
+{\bf See:}\\
+\pageto{Algebra}{ALGEBRA}
+\pageto{LieAlgebra}{LIECAT}
+\pageto{NonAssociativeAlgebra}{NAALG}
+\pageto{RectangularMatrixCategory}{RMATCAT}
+\pageto{VectorSpace}{VSPACE}
+\pagefrom{BiModule}{BMODULE}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{MODULE}{0} &
+\cross{MODULE}{coerce} &
+\cross{MODULE}{hash} &
+\cross{MODULE}{latex} &
+\cross{MODULE}{sample} \\
+\cross{MODULE}{subtractIfCan} &
+\cross{MODULE}{zero?} &
+\cross{MODULE}{?\~{}=?} &
+\cross{MODULE}{?*?} &
+\cross{MODULE}{?+?} \\
+\cross{MODULE}{?-?} &
+\cross{MODULE}{-?} &
+\cross{MODULE}{?=?} &&
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item {\bf \cross{MODULE}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{MODULE}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are implemented by this category:
+\begin{verbatim}
+ ?*? : (%,R) -> %                     
+\end{verbatim}
+
+These exports come from \refto{BiModule}(a:Ring,b:Ring):
+\begin{verbatim}
+ 0 : () -> %                          
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger            
+ latex : % -> String
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (R,%) -> %
+ ?*? : (Integer,%) -> %               
+ ?*? : (PositiveInteger,%) -> %
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?=? : (%,%) -> Boolean
+\end{verbatim}
+
+<<category MODULE Module>>=
+)abbrev category MODULE Module
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of modules over a commutative ring.
+++
+++ Axioms:
+++   \spad{1*x = x}
+++   \spad{(a*b)*x = a*(b*x)}
+++   \spad{(a+b)*x = (a*x)+(b*x)}
+++   \spad{a*(x+y) = (a*x)+(a*y)}
+Module(R:CommutativeRing): Category == BiModule(R,R)
+  add
+    if not(R is %) then x:%*r:R == r*x
+
+@
+<<MODULE.dotabb>>=
+"MODULE"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MODULE"];
+"MODULE" -> "BMODULE"
+
+@
+<<MODULE.dotfull>>=
+"Module(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MODULE"];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"Module(Field)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=MODULE"];
+"Module(Field)" -> "Module(a:CommutativeRing)"
+
+@
+<<MODULE.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"ABELGRP..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OrderedRing}{ORDRING}
 \pagepic{ps/v102orderedring.ps}{ORDRING}{0.75}
 
 {\bf See:}\\
 \pageto{DirectProductCategory}{DIRPCAT}
 \pageto{OrderedIntegralDomain}{OINTDOM}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{RealNumberSystem}{RNS}
 \pagefrom{Monoid}{MONOID}
 \pagefrom{OrderedAbelianGroup}{OAGROUP}
@@ -27373,285 +28410,284 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{PowerSeriesCategory}{PSCAT}
-\pagepic{ps/v102powerseriescategory.ps}{PSCAT}{0.60}
+\pagehead{PointCategory}{PTCAT}
+\pagepic{ps/v102pointcategory.ps}{PTCAT}{1.00}
 
 {\bf See:}\\
-\pageto{MultivariateTaylorSeriesCategory}{MTSCAT}
-\pageto{UnivariatePowerSeriesCategory}{UPSCAT}
-\pagefrom{AbelianMonoidRing}{AMR}
+\pagefrom{VectorCategory}{VECTCAT}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{PSCAT}{0} &
-\cross{PSCAT}{1} &
-\cross{PSCAT}{associates?} &
-\cross{PSCAT}{characteristic} &
-\cross{PSCAT}{charthRoot} \\
-\cross{PSCAT}{coefficient} &
-\cross{PSCAT}{coerce} &
-\cross{PSCAT}{coerce} &
-\cross{PSCAT}{coerce} &
-\cross{PSCAT}{coerce} \\
-\cross{PSCAT}{coerce} &
-\cross{PSCAT}{complete} &
-\cross{PSCAT}{degree} &
-\cross{PSCAT}{exquo} &
-\cross{PSCAT}{hash} \\
-\cross{PSCAT}{latex} &
-\cross{PSCAT}{leadingCoefficient} &
-\cross{PSCAT}{leadingMonomial} &
-\cross{PSCAT}{map} &
-\cross{PSCAT}{monomial} \\
-\cross{PSCAT}{monomial} &
-\cross{PSCAT}{monomial} &
-\cross{PSCAT}{monomial?} &
-\cross{PSCAT}{one?} &
-\cross{PSCAT}{pole?} \\
-\cross{PSCAT}{recip} &
-\cross{PSCAT}{reductum} &
-\cross{PSCAT}{sample} &
-\cross{PSCAT}{subtractIfCan} &
-\cross{PSCAT}{variables} \\
-\cross{PSCAT}{unit?} &
-\cross{PSCAT}{unitCanonical} &
-\cross{PSCAT}{unitNormal} &
-\cross{PSCAT}{zero?} &
-\cross{PSCAT}{?*?} \\
-\cross{PSCAT}{?**?} &
-\cross{PSCAT}{?+?} &
-\cross{PSCAT}{?-?} &
-\cross{PSCAT}{-?} &
-\cross{PSCAT}{?=?} \\
-\cross{PSCAT}{?\~{}=?} &
-\cross{PSCAT}{?/?} &
-\cross{PSCAT}{?\^{}?} &&
+\cross{PTCAT}{any?} &
+\cross{PTCAT}{coerce} &
+\cross{PTCAT}{concat} &
+\cross{PTCAT}{construct} &
+\cross{PTCAT}{convert} \\
+\cross{PTCAT}{copy} &
+\cross{PTCAT}{copyInto!} &
+\cross{PTCAT}{cross} &
+\cross{PTCAT}{count} &
+\cross{PTCAT}{delete} \\
+\cross{PTCAT}{dimension} &
+\cross{PTCAT}{dot} &
+\cross{PTCAT}{elt} &
+\cross{PTCAT}{empty} &
+\cross{PTCAT}{empty?} \\
+\cross{PTCAT}{entry?} &
+\cross{PTCAT}{entries} &
+\cross{PTCAT}{eq?} &
+\cross{PTCAT}{eval} &
+\cross{PTCAT}{every?} \\
+\cross{PTCAT}{extend} &
+\cross{PTCAT}{fill!} &
+\cross{PTCAT}{find} &
+\cross{PTCAT}{first} &
+\cross{PTCAT}{hash} \\
+\cross{PTCAT}{index?} &
+\cross{PTCAT}{indices} &
+\cross{PTCAT}{insert} &
+\cross{PTCAT}{latex} &
+\cross{PTCAT}{length} \\
+\cross{PTCAT}{less?} &
+\cross{PTCAT}{magnitude} &
+\cross{PTCAT}{map} &
+\cross{PTCAT}{map!} &
+\cross{PTCAT}{max} \\
+\cross{PTCAT}{maxIndex} &
+\cross{PTCAT}{member?} &
+\cross{PTCAT}{members} &
+\cross{PTCAT}{merge} &
+\cross{PTCAT}{min} \\
+\cross{PTCAT}{minIndex} &
+\cross{PTCAT}{more?} &
+\cross{PTCAT}{new} &
+\cross{PTCAT}{outerProduct} &
+\cross{PTCAT}{parts} \\
+\cross{PTCAT}{point} &
+\cross{PTCAT}{position} &
+\cross{PTCAT}{qelt} &
+\cross{PTCAT}{qsetelt!} &
+\cross{PTCAT}{reduce} \\
+\cross{PTCAT}{remove} &
+\cross{PTCAT}{removeDuplicates} &
+\cross{PTCAT}{reverse} &
+\cross{PTCAT}{reverse!} &
+\cross{PTCAT}{sample} \\
+\cross{PTCAT}{select} &
+\cross{PTCAT}{setelt} &
+\cross{PTCAT}{size?} &
+\cross{PTCAT}{sort} &
+\cross{PTCAT}{sort!} \\
+\cross{PTCAT}{sorted?} &
+\cross{PTCAT}{swap!} &
+\cross{PTCAT}{zero} &
+\cross{PTCAT}{\#?} &
+\cross{PTCAT}{?.?} \\
+\cross{PTCAT}{?\~{}=?} &
+\cross{PTCAT}{-?} &
+\cross{PTCAT}{?*?} &
+\cross{PTCAT}{?+?} &
+\cross{PTCAT}{?-?} \\
+\cross{PTCAT}{?$<$?} &
+\cross{PTCAT}{?$<=$?} &
+\cross{PTCAT}{?=?} &
+\cross{PTCAT}{?$>$?} &
+\cross{PTCAT}{?$>=$?} \\
 \end{tabular}
 
 {\bf Attributes Exported:}
 \begin{itemize}
-\item {\bf \cross{PSCAT}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{PSCAT}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{PSCAT}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\item if \#1 has IntegralDomain then noZeroDivisors where
-{\bf \cross{PSCAT}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item if \#1 has CommutativeRing then commutative(``*'') where
-{\bf \cross{PSCAT}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
+\item {\bf \cross{PTCAT}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf \cross{PTCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf nil}
 \end{itemize}
 
 These are directly exported but not implemented:
 \begin{verbatim}
- complete : % -> %                    
- degree : % -> Expon
- leadingCoefficient : % -> Coef       
- leadingMonomial : % -> %
- monomial : (%,List Var,List Expon) -> %
- monomial : (%,Var,Expon) -> %
- pole? : % -> Boolean
- variables : % -> List Var
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- ?*? : (Integer,%) -> %
- ?*? : (Coef,%) -> %                  
- ?*? : (%,Coef) -> %
- ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
- ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
- ?/? : (%,Coef) -> % if Coef has FIELD
- -? : % -> %                          
+ convert : List R -> %                
+ cross : (%,%) -> %                   
+ dimension : % -> PositiveInteger     
+ extend : (%,List R) -> %
+ point : List R -> %
 \end{verbatim}
 
-These exports come from \refto{AbelianMonoidRing}(Coef,Expon)\\
-where Coef:Ring and Expon:OrderedAbelianMonoid:
+These exports come from \refto{VectorCategory}(R:Ring):
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- associates? : (%,%) -> Boolean if Coef has INTDOM
- characteristic : () -> NonNegativeInteger
- charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
- coefficient : (%,Expon) -> Coef
- coerce : Coef -> % if Coef has COMRING
- coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
- coerce : % -> % if Coef has INTDOM
- coerce : % -> OutputForm
- coerce : Integer -> %                
- exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
- hash : % -> SingleInteger            
- latex : % -> String
- map : ((Coef -> Coef),%) -> %        
- monomial : (Coef,Expon) -> %         
- monomial? : % -> Boolean
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")       
- reductum : % -> %
+ any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ coerce : % -> OutputForm if R has SETCAT
+ concat : List % -> %
+ concat : (%,%) -> %                  
+ concat : (R,%) -> %
+ concat : (%,R) -> %                  
+ construct : List R -> %
+ convert : % -> InputForm if R has KONVERT INFORM
+ copy : % -> %
+ copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ delete : (%,Integer) -> %
+ delete : (%,UniversalSegment Integer) -> %
+ dot : (%,%) -> R if R has RING
+ elt : (%,Integer,R) -> R             
+ empty : () -> %
+ empty? : % -> Boolean                
+ entry? : (R,%) -> Boolean if $ has finiteAggregate and R has SETCAT
+ entries : % -> List R
+ eq? : (%,%) -> Boolean               
+ eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ fill! : (%,R) -> % if $ has shallowlyMutable
+ find : ((R -> Boolean),%) -> Union(R,"failed")
+ first : % -> R if Integer has ORDSET
+ hash : % -> SingleInteger if R has SETCAT
+ index? : (Integer,%) -> Boolean      
+ indices : % -> List Integer
+ insert : (%,%,Integer) -> %          
+ insert : (R,%,Integer) -> %
+ latex : % -> String if R has SETCAT
+ length : % -> R if R has RING and R has RADCAT
+ less? : (%,NonNegativeInteger) -> Boolean
+ magnitude : % -> R if R has RING and R has RADCAT
+ map : (((R,R) -> R),%,%) -> %        
+ map : ((R -> R),%) -> %
+ map! : ((R -> R),%) -> % if $ has shallowlyMutable
+ max : (%,%) -> % if R has ORDSET
+ maxIndex : % -> Integer if Integer has ORDSET
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ members : % -> List R if $ has finiteAggregate
+ merge : (%,%) -> % if R has ORDSET
+ merge : (((R,R) -> Boolean),%,%) -> %
+ min : (%,%) -> % if R has ORDSET
+ minIndex : % -> Integer if Integer has ORDSET
+ more? : (%,NonNegativeInteger) -> Boolean
+ new : (NonNegativeInteger,R) -> %    
+ outerProduct : (%,%) -> Matrix R if R has RING
+ parts : % -> List R if $ has finiteAggregate
+ position : (R,%,Integer) -> Integer if R has SETCAT
+ position : (R,%) -> Integer if R has SETCAT
+ position : ((R -> Boolean),%) -> Integer
+ qelt : (%,Integer) -> R              
+ qsetelt! : (%,Integer,R) -> R if $ has shallowlyMutable
+ reduce : (((R,R) -> R),%) -> R if $ has finiteAggregate
+ reduce : (((R,R) -> R),%,R) -> R if $ has finiteAggregate
+ reduce : (((R,R) -> R),%,R,R) -> R if R has SETCAT and $ has finiteAggregate
+ remove : ((R -> Boolean),%) -> % if $ has finiteAggregate
+ remove : (R,%) -> % if R has SETCAT and $ has finiteAggregate
+ removeDuplicates : % -> % if R has SETCAT and $ has finiteAggregate
+ reverse : % -> %
+ reverse! : % -> % if $ has shallowlyMutable
  sample : () -> %                     
- subtractIfCan : (%,%) -> Union(%,"failed")
- unit? : % -> Boolean if Coef has INTDOM
- unitCanonical : % -> % if Coef has INTDOM
- unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
-     if Coef has INTDOM
- zero? : % -> Boolean                 
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (%,%) -> %                     
- ?-? : (%,%) -> %
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
+ select : ((R -> Boolean),%) -> % if $ has finiteAggregate
+ setelt : (%,UniversalSegment Integer,R) -> R if $ has shallowlyMutable
+ setelt : (%,Integer,R) -> R if $ has shallowlyMutable
+ size? : (%,NonNegativeInteger) -> Boolean
+ sort : % -> % if R has ORDSET
+ sort : (((R,R) -> Boolean),%) -> %
+ sort! : % -> % if R has ORDSET and $ has shallowlyMutable
+ sort! : (((R,R) -> Boolean),%) -> % if $ has shallowlyMutable
+ sorted? : % -> Boolean if R has ORDSET
+ sorted? : (((R,R) -> Boolean),%) -> Boolean
+ swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
+ zero : NonNegativeInteger -> % if R has ABELMON
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?.? : (%,Integer) -> R
+ ?.? : (%,UniversalSegment Integer) -> %
+ ?~=? : (%,%) -> Boolean if R has SETCAT
+ ?<? : (%,%) -> Boolean if R has ORDSET
+ ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?=? : (%,%) -> Boolean if R has SETCAT
+ ?>? : (%,%) -> Boolean if R has ORDSET
+ ?>=? : (%,%) -> Boolean if R has ORDSET
+ ?*? : (Integer,%) -> % if R has ABELGRP
+ ?*? : (%,R) -> % if R has MONOID
+ ?*? : (R,%) -> % if R has MONOID
+ ?-? : (%,%) -> % if R has ABELGRP
+ -? : % -> % if R has ABELGRP         
+ ?+? : (%,%) -> % if R has ABELSG
 \end{verbatim}
 
-<<category PSCAT PowerSeriesCategory>>=
-)abbrev category PSCAT PowerSeriesCategory
-++ Author: Clifton J. Williamson
-++ Date Created: 21 December 1989
-++ Date Last Updated: 25 February 1990
-++ Basic Operations:
-++ Related Domains:
+<<category PTCAT PointCategory>>=
+)abbrev category PTCAT PointCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Operations: point, elt, setelt, copy, dimension, minIndex, maxIndex,
+++ convert
+++ Related Constructors:
 ++ Also See:
 ++ AMS Classifications:
-++ Keywords: power series
-++ Examples:
+++ Keywords: 
 ++ References:
-++ Description:
-++   \spadtype{PowerSeriesCategory} is the most general power series
-++   category with exponents in an ordered abelian monoid.
-PowerSeriesCategory(Coef,Expon,Var): Category == Definition where
-  Coef  : Ring
-  Expon : OrderedAbelianMonoid
-  Var   : OrderedSet
-  I   ==> Integer
-  RN  ==> Fraction Integer
-
-  Definition ==> AbelianMonoidRing(Coef,Expon) with
-    monomial: (%,Var,Expon) -> %
-      ++ \spad{monomial(a,x,n)} computes \spad{a*x**n}.
-    monomial: (%,List Var,List Expon) -> %
-      ++ \spad{monomial(a,[x1,..,xk],[n1,..,nk])} computes
-      ++ \spad{a * x1**n1 * .. * xk**nk}.
-    leadingMonomial: % -> %
-      ++ leadingMonomial(f) returns the monomial of \spad{f} of lowest order.
-    leadingCoefficient: % -> Coef
-      ++ leadingCoefficient(f) returns the coefficient of the lowest order
-      ++ term of \spad{f}
-    degree : % -> Expon
-      ++ degree(f) returns the exponent of the lowest order term of \spad{f}.
-    variables: % -> List Var
-      ++ \spad{variables(f)} returns a list of the variables occuring in the
-      ++ power series f.
-    pole?: % -> Boolean
-      ++ \spad{pole?(f)} determines if the power series f has a pole.
-    complete: % -> %
-      ++ \spad{complete(f)} causes all terms of f to be computed.
-      ++ Note: this results in an infinite loop
-      ++ if f has infinitely many terms.
-
-   add
-    n:I    * ps:% == (zero? n => 0; map(n * #1,ps))
-
-    r:Coef * ps:% == (zero? r => 0; map(r * #1,ps))
-
-    ps:% * r:Coef == (zero? r => 0; map(#1 * r,ps))
-
-    - ps          == map(- #1,ps)
-
-    if Coef has Algebra Fraction Integer then
-      r:RN * ps:% == (zero? r => 0; map(r * #1,ps))
-
-      ps:% * r:RN == (zero? r => 0; map(#1 * r,ps))
-
-    if Coef has Field then
-      ps:% / r:Coef == map(#1 / r,ps)
+++ Description: PointCategory is the category of points in space which
+++ may be plotted via the graphics facilities.  Functions are provided for
+++ defining points and handling elements of points.
+ 
+PointCategory(R:Ring) : Category == VectorCategory(R) with
+  point: List R -> %
+    ++ point(l) returns a point category defined by a list l of elements from 
+    ++ the domain R.
+  dimension: % -> PositiveInteger
+    ++ dimension(s) returns the dimension of the point category s.
+  convert: List R -> %
+    ++ convert(l) takes a list of elements, l, from the domain Ring and 
+    ++ returns the form of point category.
+  cross: (%,%) -> %
+      ++ cross(p,q) computes the cross product of the two points \spad{p}
+      ++ and \spad{q}. Error if the p and q are not 3 dimensional
+  extend : (%,List R) -> %
+	++ extend(x,l,r) \undocumented
 
 @
-<<PSCAT.dotabb>>=
-"PSCAT" 
- [color=lightblue,href="bookvol10.2.pdf#nameddest=PSCAT"];
-"PSCAT" -> "AMR"
+<<PTCAT.dotabb>>=
+"PTCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PTCAT"];
+"PTCAT" -> "VECTCAT"
 
 @
-<<PSCAT.dotfull>>=
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=PSCAT"];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=PSCAT"];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
-  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
-
-"PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=PSCAT"];
-"PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
-  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+<<PTCAT.dotfull>>=
+"PointCategory(a:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PTCAT"];
+"PointCategory(a:Ring)" -> "VectorCategory(a:Ring)"
 
 @
-<<PSCAT.dotpic>>=
+<<PTCAT.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
- [color=lightblue];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BIMODULE..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
+"PointCategory(a:Ring)" [color=lightblue];
+"PointCategory(a:Ring)" -> "VectorCategory(a:Ring)"
 
-"IntegralDomain()" [color=lightblue];
-"IntegralDomain()" -> "CommutativeRing()"
-"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
-"IntegralDomain()" -> "EntireRing()"
+"VectorCategory(a:Ring)" [color=seagreen];
+"VectorCategory(a:Ring)" -> "VectorCategory(a:Type)"
 
-"EntireRing()" [color=lightblue];
-"EntireRing()" -> "RING..."
-"EntireRing()" -> "BIMODULE..."
+"VectorCategory(a:Type)" [color=lightblue];
+"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
 
-"CharacteristicNonZero()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
-"CharacteristicNonZero()" -> "RING..."
+"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
+"OneDimensionalArrayAggregate(a:Type)" -> 
+    "FiniteLinearAggregate(a:Type)"
 
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+"FiniteLinearAggregate(a:Type)" [color=lightblue];
+"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
 
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "RING..."
-"Algebra(a:CommutativeRing)" -> "MODULE..."
+"LinearAggregate(a:Type)" [color=lightblue];
+"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
+"LinearAggregate(a:Type)" -> "CLAGG..."
 
-"CommutativeRing()" [color=lightblue];
-"CommutativeRing()" -> "RING..."
-"CommutativeRing()" -> "BIMODULE..."
+"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
+"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
 
-"BIMODULE..." [color=lightblue];
-"RING..." [color=lightblue];
-"MODULE..." [color=lightblue];
+"CLAGG..." [color=lightblue];
+"IXAGG..." [color=lightblue];
 }
 
 @
@@ -28025,6 +29061,1159 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{SquareFreeNormalizedTriangularSetCategory}{SNTSCAT}
+\pagepic{ps/v102squarefreenormalizedtriangularsetcategory.ps}{SNTSCAT}{0.45}
+
+{\bf See:}\\
+\pagefrom{NormalizedTriangularSetCategory}{NTSCAT}
+\pagefrom{SquareFreeRegularTriangularSetCategory}{SFRTCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{ll}
+\cross{SNTSCAT}{algebraic?} &
+\cross{SNTSCAT}{algebraicCoefficients?} \\
+\cross{SNTSCAT}{algebraicVariables} &
+\cross{SNTSCAT}{any?} \\
+\cross{SNTSCAT}{augment} &
+\cross{SNTSCAT}{autoReduced?} \\
+\cross{SNTSCAT}{basicSet} &
+\cross{SNTSCAT}{coerce} \\
+\cross{SNTSCAT}{coHeight} &
+\cross{SNTSCAT}{collect} \\
+\cross{SNTSCAT}{collectQuasiMonic} &
+\cross{SNTSCAT}{collectUnder} \\
+\cross{SNTSCAT}{collectUpper} &
+\cross{SNTSCAT}{construct} \\
+\cross{SNTSCAT}{convert} &
+\cross{SNTSCAT}{copy} \\
+\cross{SNTSCAT}{count} &
+\cross{SNTSCAT}{degree} \\
+\cross{SNTSCAT}{empty} &
+\cross{SNTSCAT}{empty?} \\
+\cross{SNTSCAT}{eq?} &
+\cross{SNTSCAT}{eval} \\
+\cross{SNTSCAT}{every?} &
+\cross{SNTSCAT}{extend} \\
+\cross{SNTSCAT}{extendIfCan} &
+\cross{SNTSCAT}{find} \\
+\cross{SNTSCAT}{first} &
+\cross{SNTSCAT}{hash} \\
+\cross{SNTSCAT}{headReduce} &
+\cross{SNTSCAT}{headReduced?} \\
+\cross{SNTSCAT}{headRemainder} &
+\cross{SNTSCAT}{infRittWu?} \\
+\cross{SNTSCAT}{initiallyReduce} &
+\cross{SNTSCAT}{initiallyReduced?} \\
+\cross{SNTSCAT}{initials} &
+\cross{SNTSCAT}{internalAugment} \\
+\cross{SNTSCAT}{intersect} &
+\cross{SNTSCAT}{invertible?} \\
+\cross{SNTSCAT}{invertibleElseSplit?} &
+\cross{SNTSCAT}{invertibleSet} \\
+\cross{SNTSCAT}{last} &
+\cross{SNTSCAT}{lastSubResultant} \\
+\cross{SNTSCAT}{lastSubResultantElseSplit} &
+\cross{SNTSCAT}{latex} \\
+\cross{SNTSCAT}{less?} &
+\cross{SNTSCAT}{mainVariable?} \\
+\cross{SNTSCAT}{mainVariables} &
+\cross{SNTSCAT}{map} \\
+\cross{SNTSCAT}{map!} &
+\cross{SNTSCAT}{member?} \\
+\cross{SNTSCAT}{members} &
+\cross{SNTSCAT}{more?} \\
+\cross{SNTSCAT}{mvar} &
+\cross{SNTSCAT}{normalized?} \\
+\cross{SNTSCAT}{parts} &
+\cross{SNTSCAT}{purelyAlgebraic?} \\
+\cross{SNTSCAT}{purelyAlgebraicLeadingMonomial?} &
+\cross{SNTSCAT}{purelyTranscendental?} \\
+\cross{SNTSCAT}{quasiComponent} &
+\cross{SNTSCAT}{reduce} \\
+\cross{SNTSCAT}{reduced?} &
+\cross{SNTSCAT}{reduceByQuasiMonic} \\
+\cross{SNTSCAT}{remainder} &
+\cross{SNTSCAT}{remove} \\
+\cross{SNTSCAT}{removeDuplicates} &
+\cross{SNTSCAT}{removeZero} \\
+\cross{SNTSCAT}{rest} &
+\cross{SNTSCAT}{retract} \\
+\cross{SNTSCAT}{retractIfCan} &
+\cross{SNTSCAT}{rewriteIdealWithHeadRemainder} \\
+\cross{SNTSCAT}{rewriteIdealWithRemainder} &
+\cross{SNTSCAT}{rewriteSetWithReduction} \\
+\cross{SNTSCAT}{roughBase?} &
+\cross{SNTSCAT}{roughEqualIdeals?} \\
+\cross{SNTSCAT}{roughSubIdeal?} &
+\cross{SNTSCAT}{roughUnitIdeal?} \\
+\cross{SNTSCAT}{sample} &
+\cross{SNTSCAT}{select} \\
+\cross{SNTSCAT}{size?} &
+\cross{SNTSCAT}{sort} \\
+\cross{SNTSCAT}{squareFreePart} &
+\cross{SNTSCAT}{stronglyReduce} \\
+\cross{SNTSCAT}{stronglyReduced?} &
+\cross{SNTSCAT}{triangular?} \\
+\cross{SNTSCAT}{trivialIdeal?} &
+\cross{SNTSCAT}{variables} \\
+\cross{SNTSCAT}{zeroSetSplit} &
+\cross{SNTSCAT}{zeroSetSplitIntoTriangularSystems} \\
+\cross{SNTSCAT}{\#?} &
+\cross{SNTSCAT}{?=?} \\
+\cross{SNTSCAT}{?\~{}=?} &
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{SNTSCAT}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf \cross{SNTSCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf nil}
+\end{itemize}
+
+These exports come from\\
+\refto{SquareFreeRegularTriangularSetCategory}(R,E,V,P)\\
+where R:GcdDomain, E:OrderedAbelianMonoidSup, V:OrderedSet,\\
+P:RecursivePolynomialCategory(R,E,V)):
+\begin{verbatim}
+ algebraic? : (V,%) -> Boolean
+ algebraicCoefficients? : (P,%) -> Boolean
+ algebraicVariables : % -> List V     
+ any? : ((P -> Boolean),%) -> Boolean if $ has finiteAggregate
+ augment : (List P,List %) -> List %
+ augment : (List P,%) -> List %
+ augment : (P,List %) -> List %       
+ augment : (P,%) -> List %
+ autoReduced? : (%,((P,List P) -> Boolean)) -> Boolean
+ basicSet :
+   (List P,(P -> Boolean),((P,P) -> Boolean)) ->
+      Union(Record(bas: %,top: List P),"failed")
+ basicSet :
+   (List P,((P,P) -> Boolean)) ->
+      Union(Record(bas: %,top: List P),"failed")
+ coerce : % -> List P                 
+ coerce : % -> OutputForm
+ coHeight : % -> NonNegativeInteger if V has FINITE
+ collect : (%,V) -> %                 
+ collectQuasiMonic : % -> %
+ collectUnder : (%,V) -> %            
+ collectUpper : (%,V) -> %
+ construct : List P -> %              
+ convert : % -> InputForm if P has KONVERT INFORM
+ copy : % -> %
+ count : ((P -> Boolean),%) -> NonNegativeInteger 
+   if $ has finiteAggregate
+ count : (P,%) -> NonNegativeInteger 
+   if P has SETCAT 
+   and $ has finiteAggregate
+ degree : % -> NonNegativeInteger     
+ empty : () -> %
+ empty? : % -> Boolean                
+ eq? : (%,%) -> Boolean
+ eval : (%,List Equation P) -> % if P has EVALAB P and P has SETCAT
+ eval : (%,Equation P) -> % if P has EVALAB P and P has SETCAT
+ eval : (%,P,P) -> % if P has EVALAB P and P has SETCAT
+ eval : (%,List P,List P) -> % if P has EVALAB P and P has SETCAT
+ every? : ((P -> Boolean),%) -> Boolean if $ has finiteAggregate
+ extend : (List P,List %) -> List %
+ extend : (List P,%) -> List %        
+ extend : (P,List %) -> List %
+ extend : (P,%) -> List %             
+ extend : (%,P) -> %
+ extendIfCan : (%,P) -> Union(%,"failed")
+ find : ((P -> Boolean),%) -> Union(P,"failed")
+ first : % -> Union(P,"failed")       
+ hash : % -> SingleInteger
+ headReduce : (P,%) -> P              
+ headReduced? : % -> Boolean
+ headReduced? : (P,%) -> Boolean      
+ headRemainder : (P,%) -> Record(num: P,den: R) if R has INTDOM
+ infRittWu? : (%,%) -> Boolean
+ initiallyReduce : (P,%) -> P         
+ initiallyReduced? : % -> Boolean
+ initiallyReduced? : (P,%) -> Boolean
+ initials : % -> List P               
+ internalAugment : (P,%) -> %
+ internalAugment : (List P,%) -> %
+ intersect : (List P,List %) -> List %
+ intersect : (P,List %) -> List %     
+ intersect : (List P,%) -> List %
+ intersect : (P,%) -> List %          
+ invertible? : (P,%) -> Boolean
+ invertible? : (P,%) -> List Record(val: Boolean,tower: %)
+ invertibleElseSplit? : (P,%) -> Union(Boolean,List %)
+ invertibleSet : (P,%) -> List %      
+ last : % -> Union(P,"failed")
+ lastSubResultant : (P,P,%) -> List Record(val: P,tower: %)
+ lastSubResultantElseSplit : (P,P,%) -> Union(P,List %)
+ latex : % -> String                  
+ less? : (%,NonNegativeInteger) -> Boolean
+ mainVariable? : (V,%) -> Boolean
+ mainVariables : % -> List V          
+ map : ((P -> P),%) -> %
+ map! : ((P -> P),%) -> % if $ has shallowlyMutable
+ member? : (P,%) -> Boolean if P has SETCAT and $ has finiteAggregate
+ members : % -> List P if $ has finiteAggregate
+ more? : (%,NonNegativeInteger) -> Boolean
+ mvar : % -> V                        
+ normalized? : % -> Boolean
+ normalized? : (P,%) -> Boolean       
+ parts : % -> List P if $ has finiteAggregate
+ purelyAlgebraic? : % -> Boolean
+ purelyAlgebraic? : (P,%) -> Boolean
+ purelyAlgebraicLeadingMonomial? : (P,%) -> Boolean
+ purelyTranscendental? : (P,%) -> Boolean
+ quasiComponent : % -> Record(close: List P,open: List P)
+ reduce : (P,%,((P,P) -> P),((P,P) -> Boolean)) -> P
+ reduce : (((P,P) -> P),%) -> P if $ has finiteAggregate
+ reduce : (((P,P) -> P),%,P) -> P if $ has finiteAggregate
+ reduce : (((P,P) -> P),%,P,P) -> P 
+   if P has SETCAT 
+   and $ has finiteAggregate
+ reduced? : (P,%,((P,P) -> Boolean)) -> Boolean
+ reduceByQuasiMonic : (P,%) -> P      
+ remainder : (P,%) -> Record(rnum: R,polnum: P,den: R) if R has INTDOM
+ remove : ((P -> Boolean),%) -> % if $ has finiteAggregate
+ remove : (P,%) -> % if P has SETCAT and $ has finiteAggregate
+ removeDuplicates : % -> % if P has SETCAT and $ has finiteAggregate
+ removeZero : (P,%) -> P
+ rest : % -> Union(%,"failed")        
+ retract : List P -> %
+ retractIfCan : List P -> Union(%,"failed")
+ rewriteIdealWithHeadRemainder : (List P,%) -> List P if R has INTDOM
+ rewriteIdealWithRemainder : (List P,%) -> List P if R has INTDOM
+ rewriteSetWithReduction :
+    (List P,%,((P,P) -> P),((P,P) -> Boolean)) -> List P
+ roughBase? : % -> Boolean if R has INTDOM
+ roughEqualIdeals? : (%,%) -> Boolean if R has INTDOM
+ roughSubIdeal? : (%,%) -> Boolean if R has INTDOM
+ roughUnitIdeal? : % -> Boolean if R has INTDOM
+ sample : () -> %                     
+ select : (%,V) -> Union(P,"failed")
+ select : ((P -> Boolean),%) -> % if $ has finiteAggregate
+ size? : (%,NonNegativeInteger) -> Boolean
+ sort : (%,V) -> Record(under: %,floor: %,upper: %)
+ squareFreePart : (P,%) -> List Record(val: P,tower: %)
+ stronglyReduce : (P,%) -> P
+ stronglyReduced? : (P,%) -> Boolean
+ stronglyReduced? : % -> Boolean      
+ triangular? : % -> Boolean if R has INTDOM
+ trivialIdeal? : % -> Boolean
+ variables : % -> List V              
+ zeroSetSplit : List P -> List %
+ zeroSetSplit : (List P,Boolean) -> List %
+ zeroSetSplitIntoTriangularSystems :
+    List P -> List Record(close: %,open: List P)
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+\end{verbatim}
+
+<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>=
+)abbrev category SNTSCAT SquareFreeNormalizedTriangularSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 10/07/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: essai Graphisme
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of square-free and normalized triangular sets.
+++ Thus, up to the primitivity axiom of [1], these sets are Lazard
+++ triangular sets.\newline
+++ References :
+++  [1] D. LAZARD "A new method for solving algebraic systems of 
+++      positive dimension" Discr. App. Math. 33:147-160,1991
+SquareFreeNormalizedTriangularSetCategory(R:GcdDomain,_
+                                          E:OrderedAbelianMonoidSup,_
+                                          V:OrderedSet,_
+                                         P:RecursivePolynomialCategory(R,E,V)):
+         Category == 
+   Join(SquareFreeRegularTriangularSetCategory(R,E,V,P), _
+        NormalizedTriangularSetCategory(R,E,V,P))
+
+@
+<<SNTSCAT.dotabb>>=
+"SNTSCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=SNTSCAT"];
+"SNTSCAT" -> "NTSCAT"
+"SNTSCAT" -> "SFRTCAT"
+
+@
+<<SNTSCAT.dotfull>>=
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=SNTSCAT"];
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ ->
+"SquareFreeRegularTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ ->
+"NormalizedRegularTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+
+@
+<<SNTSCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ [color=lightblue];
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ -> "SFRTCAT..."
+
+"SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))"
+ -> "NTSCAT..."
+
+"SFRTCAT..."  [color=lightblue];
+"NTSCAT..."  [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{StringCategory}{STRICAT}
+\pagepic{ps/v102stringcategory.ps}{STRICAT}{0.75}
+
+{\bf See:}\\
+\pagefrom{OpenMath}{OM}
+\pagefrom{SetCategory}{SETCAT}
+\pagefrom{StringAggregate}{SRAGG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{STRICAT}{any?} &
+\cross{STRICAT}{coerce} &
+\cross{STRICAT}{concat} &
+\cross{STRICAT}{construct} &
+\cross{STRICAT}{convert} \\
+\cross{STRICAT}{copy} &
+\cross{STRICAT}{copyInto!} &
+\cross{STRICAT}{count} &
+\cross{STRICAT}{delete} &
+\cross{STRICAT}{elt} \\
+\cross{STRICAT}{empty} &
+\cross{STRICAT}{empty?} &
+\cross{STRICAT}{entry?} &
+\cross{STRICAT}{entries} &
+\cross{STRICAT}{eq?} \\
+\cross{STRICAT}{eval} &
+\cross{STRICAT}{every?} &
+\cross{STRICAT}{fill!} &
+\cross{STRICAT}{find} &
+\cross{STRICAT}{first} \\
+\cross{STRICAT}{hash} &
+\cross{STRICAT}{index?} &
+\cross{STRICAT}{indices} &
+\cross{STRICAT}{insert} &
+\cross{STRICAT}{latex} \\
+\cross{STRICAT}{leftTrim} &
+\cross{STRICAT}{less?} &
+\cross{STRICAT}{lowerCase} &
+\cross{STRICAT}{lowerCase!} &
+\cross{STRICAT}{map} \\
+\cross{STRICAT}{map!} &
+\cross{STRICAT}{match} &
+\cross{STRICAT}{match?} &
+\cross{STRICAT}{max} &
+\cross{STRICAT}{maxIndex} \\
+\cross{STRICAT}{member?} &
+\cross{STRICAT}{members} &
+\cross{STRICAT}{merge} &
+\cross{STRICAT}{min} &
+\cross{STRICAT}{minIndex} \\
+\cross{STRICAT}{more?} &
+\cross{STRICAT}{new} &
+\cross{STRICAT}{OMwrite} &
+\cross{STRICAT}{parts} &
+\cross{STRICAT}{position} \\
+\cross{STRICAT}{prefix?} &
+\cross{STRICAT}{qelt} &
+\cross{STRICAT}{qsetelt!} &
+\cross{STRICAT}{reduce} &
+\cross{STRICAT}{remove} \\
+\cross{STRICAT}{removeDuplicates} &
+\cross{STRICAT}{replace} &
+\cross{STRICAT}{reverse} &
+\cross{STRICAT}{reverse!} &
+\cross{STRICAT}{rightTrim} \\
+\cross{STRICAT}{sample} &
+\cross{STRICAT}{select} &
+\cross{STRICAT}{setelt} &
+\cross{STRICAT}{size?} &
+\cross{STRICAT}{sort} \\
+\cross{STRICAT}{sort!} &
+\cross{STRICAT}{sorted?} &
+\cross{STRICAT}{sorted?} &
+\cross{STRICAT}{split} &
+\cross{STRICAT}{string} \\
+\cross{STRICAT}{substring?} &
+\cross{STRICAT}{suffix?} &
+\cross{STRICAT}{swap!} &
+\cross{STRICAT}{trim} &
+\cross{STRICAT}{upperCase} \\
+\cross{STRICAT}{upperCase!} &
+\cross{STRICAT}{\#?} &
+\cross{STRICAT}{?$<$?} &
+\cross{STRICAT}{?$<=$?} &
+\cross{STRICAT}{?$>$?} \\
+\cross{STRICAT}{?$>=$?} &
+\cross{STRICAT}{?=?} &
+\cross{STRICAT}{?.?} &
+\cross{STRICAT}{?\~{}=?} &
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item {\bf \cross{STRICAT}{shallowlyMutable}}
+is true if its values have immediate components that are 
+updateable (mutable). Note: the properties of any component 
+domain are irrevelant to the shallowlyMutable proper.
+\item {\bf \cross{STRICAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf nil}
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ string : Integer -> %                
+\end{verbatim}
+
+These exports come from \refto{StringAggregate}():
+\begin{verbatim}
+ any? : ((Character -> Boolean),%) -> Boolean 
+     if $ has finiteAggregate
+ coerce : % -> OutputForm
+ coerce : Character -> %              
+ concat : List % -> %
+ concat : (%,%) -> %                  
+ concat : (Character,%) -> %
+ concat : (%,Character) -> %          
+ construct : List Character -> %
+ convert : % -> InputForm 
+     if Character has KONVERT INFORM
+ copy : % -> %                        
+ copyInto! : (%,%,Integer) -> % 
+     if $ has shallowlyMutable
+ count : (Character,%) -> NonNegativeInteger 
+     if Character has SETCAT 
+     and $ has finiteAggregate
+ count : ((Character -> Boolean),%) -> NonNegativeInteger 
+     if $ has finiteAggregate
+ delete : (%,UniversalSegment Integer) -> %
+ delete : (%,Integer) -> %
+ elt : (%,Integer,Character) -> Character
+ empty : () -> %                      
+ empty? : % -> Boolean
+ entry? : (Character,%) -> Boolean 
+     if $ has finiteAggregate 
+     and Character has SETCAT
+ entries : % -> List Character        
+ eq? : (%,%) -> Boolean
+ eval : (%,List Character,List Character) -> % 
+     if Character has EVALAB CHAR 
+     and Character has SETCAT
+ eval : (%,Character,Character) -> % 
+     if Character has EVALAB CHAR 
+     and Character has SETCAT
+ eval : (%,Equation Character) -> % 
+     if Character has EVALAB CHAR 
+     and Character has SETCAT
+ eval : (%,List Equation Character) -> % 
+     if Character has EVALAB CHAR 
+     and Character has SETCAT
+ every? : ((Character -> Boolean),%) -> Boolean 
+     if $ has finiteAggregate
+ fill! : (%,Character) -> % 
+     if $ has shallowlyMutable
+ find : ((Character -> Boolean),%) -> Union(Character,"failed")
+ first : % -> Character 
+     if Integer has ORDSET
+ hash : % -> SingleInteger            
+ index? : (Integer,%) -> Boolean
+ indices : % -> List Integer          
+ insert : (%,%,Integer) -> %
+ insert : (Character,%,Integer) -> %
+ latex : % -> String                  
+ leftTrim : (%,Character) -> %
+ leftTrim : (%,CharacterClass) -> %
+ less? : (%,NonNegativeInteger) -> Boolean
+ lowerCase : % -> %                   
+ lowerCase! : % -> %
+ map : (((Character,Character) -> Character),%,%) -> %
+ map : ((Character -> Character),%) -> %
+ map! : ((Character -> Character),%) -> % 
+     if $ has shallowlyMutable
+ match : (%,%,Character) -> NonNegativeInteger
+ match? : (%,%,Character) -> Boolean
+ max : (%,%) -> % if Character has ORDSET
+ maxIndex : % -> Integer if Integer has ORDSET
+ member? : (Character,%) -> Boolean 
+     if Character has SETCAT 
+     and $ has finiteAggregate
+ members : % -> List Character 
+     if $ has finiteAggregate
+ merge : (%,%) -> % if Character has ORDSET
+ merge : (((Character,Character) -> Boolean),%,%) -> %
+ min : (%,%) -> % if Character has ORDSET
+ minIndex : % -> Integer if Integer has ORDSET
+ more? : (%,NonNegativeInteger) -> Boolean
+ new : (NonNegativeInteger,Character) -> %
+ parts : % -> List Character if $ has finiteAggregate
+ position : (Character,%) -> Integer 
+     if Character has SETCAT
+ position : ((Character -> Boolean),%) -> Integer
+ position : (Character,%,Integer) -> Integer 
+     if Character has SETCAT
+ position : (CharacterClass,%,Integer) -> Integer
+ position : (%,%,Integer) -> Integer
+ prefix? : (%,%) -> Boolean           
+ qelt : (%,Integer) -> Character
+ qsetelt! : (%,Integer,Character) -> Character 
+     if $ has shallowlyMutable
+ reduce : (((Character,Character) -> Character),%)
+    -> Character 
+     if $ has finiteAggregate
+ reduce : (((Character,Character) -> Character),%,Character)
+    -> Character 
+     if $ has finiteAggregate
+ reduce :
+  (((Character,Character) -> Character),%,Character,Character)
+    -> Character 
+     if Character has SETCAT 
+     and $ has finiteAggregate
+ remove : ((Character -> Boolean),%) -> % 
+     if $ has finiteAggregate
+ remove : (Character,%) -> % 
+     if Character has SETCAT 
+     and $ has finiteAggregate
+ removeDuplicates : % -> % 
+     if Character has SETCAT 
+     and $ has finiteAggregate
+ replace : (%,UniversalSegment Integer,%) -> %
+ reverse : % -> %                     
+ reverse! : % -> % if $ has shallowlyMutable
+ rightTrim : (%,CharacterClass) -> %
+ rightTrim : (%,Character) -> %
+ sample : () -> %                     
+ select : ((Character -> Boolean),%) -> % 
+     if $ has finiteAggregate
+ setelt : 
+   (%,UniversalSegment Integer,Character) -> Character 
+     if $ has shallowlyMutable
+ setelt : (%,Integer,Character) -> Character 
+     if $ has shallowlyMutable
+ size? : (%,NonNegativeInteger) -> Boolean
+ sort : % -> % if Character has ORDSET
+ sort : (((Character,Character) -> Boolean),%) -> %
+ sort! : % -> % 
+     if Character has ORDSET 
+     and $ has shallowlyMutable
+ sort! : (((Character,Character) -> Boolean),%) -> % 
+     if $ has shallowlyMutable
+ sorted? : (((Character,Character) -> Boolean),%) -> Boolean
+ sorted? : % -> Boolean if Character has ORDSET
+ split : (%,CharacterClass) -> List %
+ split : (%,Character) -> List %
+ substring? : (%,%,Integer) -> Boolean
+ suffix? : (%,%) -> Boolean
+ swap! : (%,Integer,Integer) -> Void 
+     if $ has shallowlyMutable
+ trim : (%,CharacterClass) -> %       
+ trim : (%,Character) -> %
+ upperCase : % -> %                   
+ upperCase! : % -> %
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?<? : (%,%) -> Boolean if Character has ORDSET
+ ?<=? : (%,%) -> Boolean if Character has ORDSET
+ ?>? : (%,%) -> Boolean if Character has ORDSET
+ ?>=? : (%,%) -> Boolean if Character has ORDSET
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+ ?.? : (%,UniversalSegment Integer) -> %
+ ?.? : (%,Integer) -> Character
+ ?.? : (%,%) -> %                     
+\end{verbatim}
+
+These exports come from \refto{SetCategory}():
+\begin{verbatim}
+\end{verbatim}
+
+These exports come from \refto{OpenMath}():
+\begin{verbatim}
+ OMwrite : (%,Boolean) -> String
+ OMwrite : % -> String                
+ OMwrite : (OpenMathDevice,%,Boolean) -> Void
+ OMwrite : (OpenMathDevice,%) -> Void
+\end{verbatim}
+
+<<category STRICAT StringCategory>>=
+)abbrev category STRICAT StringCategory
+-- Note that StringCategory is built into the old compiler
+-- redundant SetCategory added to help A# compiler
+++ Description:
+++ A category for string-like objects
+
+StringCategory():Category == _
+     Join(StringAggregate(), SetCategory, OpenMath) with
+  string: Integer -> %
+    ++ string(i) returns the decimal representation of i in a string
+
+@
+<<STRICAT.dotabb>>=
+"STRICAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=STRICAT"];
+"STRICAT" -> "OM"
+"STRICAT" -> "SETCAT"
+"STRICAT" -> "SRAGG"
+
+@
+<<STRICAT.dotfull>>=
+"StringCategory()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=STRICAT"];
+"StringCategory()" -> "OpenMath()"
+"StringCategory()" -> "SetCategory()"
+"StringCategory()" -> "StringAggregate()"
+
+@
+<<STRICAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"StringCategory()" [color=lightblue];
+"StringCategory()" -> "OpenMath()"
+"StringCategory()" -> "SetCategory()"
+"StringCategory()" -> "StringAggregate()"
+
+"OpenMath()" [color=lightblue];
+"OpenMath()" -> "Category"
+
+"SetCategory()" [color=lightblue];
+"SetCategory()" -> "BasicType()"
+"SetCategory()" -> "CoercibleTo(OutputForm)"
+
+"BasicType()" [color=lightblue];
+"BasicType()" -> "Category"
+
+"CoercibleTo(OutputForm)" [color=seagreen];
+"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+
+"CoercibleTo(a:Type)" [color=lightblue];
+"CoercibleTo(a:Type)" -> "Category"
+
+"StringAggregate()" [color=lightblue];
+"StringAggregate()" -> "A1AGG..."
+
+"A1AGG..." [color=lightblue];
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{UnivariateSkewPolynomialCategory}{OREPCAT}
+\pagepic{ps/v102univariateskewpolynomialcategory.ps}{OREPCAT}{0.55}
+
+{\bf See:}\\
+\pageto{LinearOrdinaryDifferentialOperatorCategory}{LODOCAT}
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{Ring}{RING}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{OREPCAT}{0} &
+\cross{OREPCAT}{1} &
+\cross{OREPCAT}{apply} &
+\cross{OREPCAT}{characteristic} \\
+\cross{OREPCAT}{coefficient} &
+\cross{OREPCAT}{coefficients} &
+\cross{OREPCAT}{coerce} &
+\cross{OREPCAT}{content} \\
+\cross{OREPCAT}{degree} &
+\cross{OREPCAT}{exquo} &
+\cross{OREPCAT}{hash} &
+\cross{OREPCAT}{latex} \\
+\cross{OREPCAT}{leadingCoefficient} &
+\cross{OREPCAT}{leftDivide} &
+\cross{OREPCAT}{leftExactQuotient} &
+\cross{OREPCAT}{leftExtendedGcd} \\
+\cross{OREPCAT}{leftGcd} &
+\cross{OREPCAT}{leftLcm} &
+\cross{OREPCAT}{leftQuotient} &
+\cross{OREPCAT}{leftRemainder} \\
+\cross{OREPCAT}{minimumDegree} &
+\cross{OREPCAT}{monicLeftDivide} &
+\cross{OREPCAT}{monicRightDivide} &
+\cross{OREPCAT}{monomial} \\
+\cross{OREPCAT}{one?} &
+\cross{OREPCAT}{primitivePart} &
+\cross{OREPCAT}{recip} &
+\cross{OREPCAT}{reductum} \\
+\cross{OREPCAT}{retract} &
+\cross{OREPCAT}{retractIfCan} &
+\cross{OREPCAT}{rightDivide} &
+\cross{OREPCAT}{rightExactQuotient} \\
+\cross{OREPCAT}{rightExtendedGcd} &
+\cross{OREPCAT}{rightGcd} &
+\cross{OREPCAT}{rightLcm} &
+\cross{OREPCAT}{rightQuotient} \\
+\cross{OREPCAT}{rightRemainder} &
+\cross{OREPCAT}{sample} &
+\cross{OREPCAT}{subtractIfCan} &
+\cross{OREPCAT}{zero?} \\
+\cross{OREPCAT}{?*?} &
+\cross{OREPCAT}{?**?} &
+\cross{OREPCAT}{?+?} &
+\cross{OREPCAT}{?-?} \\
+\cross{OREPCAT}{-?} &
+\cross{OREPCAT}{?=?} &
+\cross{OREPCAT}{?\^{}?} &
+\cross{OREPCAT}{?\~{}=?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{OREPCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{OREPCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{OREPCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ apply : (%,R,R) -> R
+ coefficient : (%,NonNegativeInteger) -> R
+ degree : % -> NonNegativeInteger     
+ leadingCoefficient : % -> R
+ leftDivide : (%,%) -> Record(quotient: %,remainder: %) if R has FIELD
+ minimumDegree : % -> NonNegativeInteger
+ monicLeftDivide : (%,%) -> Record(quotient: %,remainder: %) if R has INTDOM
+ monicRightDivide : (%,%) -> Record(quotient: %,remainder: %) if R has INTDOM
+ monomial : (R,NonNegativeInteger) -> %
+ reductum : % -> %                    
+ rightDivide : (%,%) -> Record(quotient: %,remainder: %) if R has FIELD
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ coefficients : % -> List R           
+ coerce : R -> %
+ content : % -> R if R has GCDDOM
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ leftExactQuotient : (%,%) -> Union(%,"failed") if R has FIELD
+ leftExtendedGcd : (%,%) -> Record(coef1: %,coef2: %,generator: %) if R has FIELD
+ leftGcd : (%,%) -> % if R has FIELD
+ leftLcm : (%,%) -> % if R has FIELD
+ leftQuotient : (%,%) -> % if R has FIELD
+ leftRemainder : (%,%) -> % if R has FIELD
+ primitivePart : % -> % if R has GCDDOM
+ retractIfCan : % -> Union(R,"failed")
+ rightExactQuotient : (%,%) -> Union(%,"failed") if R has FIELD
+ rightExtendedGcd : (%,%) -> Record(coef1: %,coef2: %,generator: %) if R has FIELD
+ rightGcd : (%,%) -> % if R has FIELD
+ rightLcm : (%,%) -> % if R has FIELD
+ rightQuotient : (%,%) -> % if R has FIELD
+ rightRemainder : (%,%) -> % if R has FIELD
+ ?*? : (R,%) -> %                     
+\end{verbatim}
+
+These exports come from \refto{Ring}():
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ characteristic : () -> NonNegativeInteger
+ coerce : % -> OutputForm
+ coerce : Integer -> %                
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+These exports come from \refto{BiModule}(R:Ring,R:Ring):
+\begin{verbatim}
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(R:Ring):
+\begin{verbatim}
+ coerce : Fraction Integer -> % if R has RETRACT FRAC INT
+ retract : % -> R
+ retract : % -> Fraction Integer if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
+\end{verbatim}
+
+<<category OREPCAT UnivariateSkewPolynomialCategory>>=
+)abbrev category OREPCAT UnivariateSkewPolynomialCategory
+++ Author: Manuel Bronstein, Jean Della Dora, Stephen M. Watt
+++ Date Created: 19 October 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++   This is the category of univariate skew polynomials over an Ore
+++   coefficient ring.
+++   The multiplication is given by \spad{x a = \sigma(a) x + \delta a}.
+++   This category is an evolution of the types
+++     MonogenicLinearOperator, OppositeMonogenicLinearOperator, and
+++     NonCommutativeOperatorDivision
+++   developped by Jean Della Dora and Stephen M. Watt.
+UnivariateSkewPolynomialCategory(R:Ring):
+  Category == Join(Ring, BiModule(R, R), FullyRetractableTo R) with
+      degree: $ -> NonNegativeInteger
+          ++ degree(l) is \spad{n} if
+          ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+      minimumDegree: $ -> NonNegativeInteger
+          ++ minimumDegree(l) is the smallest \spad{k} such that
+          ++ \spad{a(k) ^= 0} if
+          ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+      leadingCoefficient: $ -> R
+          ++ leadingCoefficient(l) is \spad{a(n)} if
+          ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+      reductum: $ -> $
+          ++ reductum(l) is \spad{l - monomial(a(n),n)} if
+          ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+      coefficient: ($, NonNegativeInteger) -> R
+          ++ coefficient(l,k) is \spad{a(k)} if
+          ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+      monomial: (R, NonNegativeInteger) -> $
+          ++ monomial(c,k) produces c times the k-th power of
+          ++ the generating operator, \spad{monomial(1,1)}.
+      coefficients: % -> List R
+          ++ coefficients(l) returns the list of all the nonzero
+          ++ coefficients of l.
+      apply: (%, R, R) -> R
+        ++ apply(p, c, m) returns \spad{p(m)} where the action is
+        ++ given by \spad{x m = c sigma(m) + delta(m)}.
+      if R has CommutativeRing then Algebra R
+      if R has IntegralDomain then
+        "exquo": (%, R) -> Union(%, "failed")
+          ++ exquo(l, a) returns the exact quotient of l by a, 
+          ++ returning \axiom{"failed"} if this is not possible.
+        monicLeftDivide:   (%, %) -> Record(quotient: %, remainder: %)
+          ++ monicLeftDivide(a,b) returns the pair \spad{[q,r]} such that
+          ++ \spad{a = b*q + r} and the degree of \spad{r} is
+          ++ less than the degree of \spad{b}.
+          ++ \spad{b} must be monic.
+          ++ This process is called ``left division''.
+        monicRightDivide:   (%, %) -> Record(quotient: %, remainder: %)
+          ++ monicRightDivide(a,b) 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''.
+      if R has GcdDomain then
+        content: % -> R
+          ++ content(l) returns the gcd of all the coefficients of l.
+        primitivePart: % -> %
+          ++ primitivePart(l) returns l0 such that \spad{l = a * l0}
+          ++ for some a in R, and \spad{content(l0) = 1}.
+      if R has Field then
+        leftDivide:   (%, %) -> Record(quotient: %, remainder: %)
+          ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
+          ++ \spad{a = b*q + r} and the degree of \spad{r} is
+          ++ less than the degree of \spad{b}.
+          ++ This process is called ``left division''.
+        leftQuotient:  (%, %) -> %
+          ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
+          ++ \spad{a = b*q + r} and the degree of \spad{r} is
+          ++ less than the degree of \spad{b}.
+          ++ The value \spad{q} is returned.
+        leftRemainder:  (%, %) -> %
+          ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
+          ++ \spad{a = b*q + r} and the degree of \spad{r} is
+          ++ less than the degree of \spad{b}.
+          ++ The value \spad{r} is returned.
+        leftExactQuotient:(%, %) -> Union(%, "failed")
+          ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
+          ++  such that \spad{a = b*q}.
+        leftGcd:   (%, %) -> %
+          ++ leftGcd(a,b) computes the value \spad{g} of highest degree
+          ++ such that
+          ++    \spad{a = g*aa}
+          ++    \spad{b = g*bb}
+          ++ for some values \spad{aa} and \spad{bb}.
+          ++ The value \spad{g} is computed using left-division.
+        leftExtendedGcd:   (%, %) -> Record(coef1:%, coef2:%, generator:%)
+          ++ leftExtendedGcd(a,b) returns \spad{[c,d]} such that
+          ++ \spad{g = a * c + b * d = leftGcd(a, b)}.
+        rightLcm:   (%, %) -> %
+          ++ rightLcm(a,b) computes the value \spad{m} of lowest degree
+          ++ such that \spad{m = a*aa = b*bb} for some values
+          ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
+          ++ computed using left-division.
+        rightDivide:   (%, %) -> Record(quotient: %, remainder: %)
+          ++ rightDivide(a,b) 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''.
+        rightQuotient:  (%, %) -> %
+          ++ rightQuotient(a,b) computes 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}.
+          ++ The value \spad{q} is returned.
+        rightRemainder:  (%, %) -> %
+          ++ rightRemainder(a,b) computes 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}.
+          ++ The value \spad{r} is returned.
+        rightExactQuotient:(%, %) -> Union(%, "failed")
+          ++ rightExactQuotient(a,b) computes the value \spad{q}, if it exists
+          ++ such that \spad{a = q*b}.
+        rightGcd:   (%, %) -> %
+          ++ rightGcd(a,b) computes the value \spad{g} of highest degree
+          ++ such that
+          ++    \spad{a = aa*g}
+          ++    \spad{b = bb*g}
+          ++ for some values \spad{aa} and \spad{bb}.
+          ++ The value \spad{g} is computed using right-division.
+        rightExtendedGcd:   (%, %) -> Record(coef1:%, coef2:%, generator:%)
+          ++ rightExtendedGcd(a,b) returns \spad{[c,d]} such that
+          ++ \spad{g = c * a + d * b = rightGcd(a, b)}.
+        leftLcm:   (%, %) -> %
+          ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
+          ++ such that \spad{m = aa*a = bb*b} for some values
+          ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
+          ++ computed using right-division.
+ 
+   add
+      coerce(x:R):% == monomial(x, 0)
+ 
+      coefficients l ==
+        ans:List(R) := empty()
+        while l ^= 0 repeat
+          ans := concat(leadingCoefficient l, ans)
+          l   := reductum l
+        ans
+ 
+      a:R * y:% ==
+        z:% := 0
+        while y ^= 0 repeat
+          z := z + monomial(a * leadingCoefficient y, degree y)
+          y := reductum y
+        z
+ 
+      retractIfCan(x:%):Union(R, "failed") ==
+        zero? x or zero? degree x => leadingCoefficient x
+        "failed"
+ 
+      if R has IntegralDomain then
+        l exquo a ==
+          ans:% := 0
+          while l ^= 0 repeat
+            (u := (leadingCoefficient(l) exquo a)) case "failed" =>
+               return "failed"
+            ans := ans + monomial(u::R, degree l)
+            l   := reductum l
+          ans
+ 
+      if R has GcdDomain then
+        content l       == gcd coefficients l
+
+        primitivePart l == (l exquo content l)::%
+ 
+      if R has Field then
+        leftEEA:  (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
+        rightEEA: (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
+        ncgcd:    (%, %, (%, %) -> %) -> %
+        nclcm:  (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) -> %
+        exactQuotient: Record(quotient:%, remainder:%) -> Union(%, "failed")
+        extended: (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) ->
+                                        Record(coef1:%, coef2:%, generator:%)
+ 
+        leftQuotient(a, b)         == leftDivide(a,b).quotient
+
+        leftRemainder(a, b)        == leftDivide(a,b).remainder
+
+        leftExtendedGcd(a, b)      == extended(a, b, leftEEA)
+
+        rightLcm(a, b)             == nclcm(a, b, leftEEA)
+
+        rightQuotient(a, b)        == rightDivide(a,b).quotient
+
+        rightRemainder(a, b)       == rightDivide(a,b).remainder
+
+        rightExtendedGcd(a, b)     == extended(a, b, rightEEA)
+
+        leftLcm(a, b)              == nclcm(a, b, rightEEA)
+
+        leftExactQuotient(a, b)    == exactQuotient leftDivide(a, b)
+
+        rightExactQuotient(a, b)   == exactQuotient rightDivide(a, b)
+
+        rightGcd(a, b)             == ncgcd(a, b, rightRemainder)
+
+        leftGcd(a, b)              == ncgcd(a, b, leftRemainder)
+
+        exactQuotient qr  == (zero?(qr.remainder) => qr.quotient; "failed")
+ 
+        -- returns [g = leftGcd(a, b), c, d, l = rightLcm(a, b)]
+        -- such that g := a c + b d
+        leftEEA(a, b) ==
+          a0 := a
+          u0:% := v:% := 1
+          v0:% := u:% := 0
+          while b ^= 0 repeat
+            qr     := leftDivide(a, b)
+            (a, b) := (b, qr.remainder)
+            (u0, u):= (u, u0 - u * qr.quotient)
+            (v0, v):= (v, v0 - v * qr.quotient)
+          [a, u0, v0, a0 * u]
+ 
+        ncgcd(a, b, ncrem) ==
+          zero? a => b
+          zero? b => a
+          degree a < degree b => ncgcd(b, a, ncrem)
+          while b ^= 0 repeat (a, b) := (b, ncrem(a, b))
+          a
+ 
+        extended(a, b, eea) ==
+          zero? a => [0, 1, b]
+          zero? b => [1, 0, a]
+          degree a < degree b =>
+            rec := eea(b, a)
+            [rec.coef2, rec.coef1, rec.gcd]
+          rec := eea(a, b)
+          [rec.coef1, rec.coef2, rec.gcd]
+ 
+        nclcm(a, b, eea) ==
+          zero? a or zero? b => 0
+          degree a < degree b => nclcm(b, a, eea)
+          rec := eea(a, b)
+          rec.lcm
+ 
+        -- returns [g = rightGcd(a, b), c, d, l = leftLcm(a, b)]
+        -- such that g := a c + b d
+        rightEEA(a, b) ==
+          a0 := a
+          u0:% := v:% := 1
+          v0:% := u:% := 0
+          while b ^= 0 repeat
+            qr     := rightDivide(a, b)
+            (a, b) := (b, qr.remainder)
+            (u0, u):= (u, u0 - qr.quotient * u)
+            (v0, v):= (v, v0 - qr.quotient * v)
+          [a, u0, v0, u * a0]
+
+@
+<<OREPCAT.dotabb>>=
+"OREPCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=OREPCAT"];
+"OREPCAT" -> "BMODULE"
+"OREPCAT" -> "FRETRCT"
+"OREPCAT" -> "RING"
+
+@
+<<OREPCAT.dotfull>>=
+"UnivariateSkewPolynomialCategory(R:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=OREPCAT"];
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "BiModule(a:Ring,b:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "FullyRetractableTo(a:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "Ring()"
+
+@
+<<OREPCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"UnivariateSkewPolynomialCategory(R:Ring)" [color=lightblue];
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "BiModule(a:Ring,b:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "FullyRetractableTo(a:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "Ring()"
+
+"FullyRetractableTo(a:Ring)" [color=seagreen];
+"FullyRetractableTo(a:Ring)" -> "FullyRetractableTo(a:Type)"
+
+"FullyRetractableTo(a:Type)" [color=lightblue];
+"FullyRetractableTo(a:Type)" -> "RetractableTo(a:Type)"
+
+"RetractableTo(a:Type)" [color=lightblue];
+"RetractableTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+"Ring()" [color=lightblue];
+"Ring()" -> "Rng()"
+"Ring()" -> "Monoid()"
+"Ring()" -> "LeftModule(a:Ring)"
+
+"Rng()" [color=lightblue];
+"Rng()" -> "AbelianGroup()"
+"Rng()" -> "SemiGroup()"
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SemiGroup()"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "AbelianGroup()"
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "AbelianGroup()"
+
+"AbelianGroup()" [color=lightblue];
+"AbelianGroup()" -> "CABMON..."
+"AbelianGroup()" -> "REPDB..."
+
+"SemiGroup()" [color=lightblue];
+"SemiGroup()" -> "SETCAT..."
+"SemiGroup()" -> "REPSQ..."
+
+"REPDB..." [color="#00EE00"];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"CABMON..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{XAlgebra}{XALG}
 \pagepic{ps/v102xalgebra.ps}{XALG}{0.70}
 
@@ -28201,12 +30390,224 @@ digraph pic {
 @
 \chapter{Category Layer 10}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{Algebra}{ALGEBRA}
+\pagepic{ps/v102algebra.ps}{ALGEBRA}{0.65}
+
+{\bf See:}\\
+\pageto{DivisionRing}{DIVRING}
+\pageto{FiniteRankAlgebra}{FINRALG}
+\pageto{FunctionSpace}{FS}
+\pageto{IntegralDomain}{INTDOM}
+\pageto{MonogenicLinearOperator}{MLO}
+\pageto{OctonionCategory}{OC}
+\pageto{QuotientFieldCategory}{QFCAT}
+\pageto{QuaternionCategory}{QUATCAT}
+\pageto{RealClosedField}{RCFIELD}
+\pagefrom{Module}{MODULE}
+\pagefrom{Ring}{RING}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{ALGEBRA}{1} &
+\cross{ALGEBRA}{0} &
+\cross{ALGEBRA}{characteristic} &
+\cross{ALGEBRA}{coerce} &
+\cross{ALGEBRA}{hash} \\
+\cross{ALGEBRA}{latex} &
+\cross{ALGEBRA}{one?} &
+\cross{ALGEBRA}{recip} &
+\cross{ALGEBRA}{sample} &
+\cross{ALGEBRA}{subtractIfCan} \\
+\cross{ALGEBRA}{zero?} &
+\cross{ALGEBRA}{?*?} &
+\cross{ALGEBRA}{?+?} &
+\cross{ALGEBRA}{?-?} &
+\cross{ALGEBRA}{-?} \\
+\cross{ALGEBRA}{?=?} &
+\cross{ALGEBRA}{?\~{}=?} &
+\cross{ALGEBRA}{?*?} &
+\cross{ALGEBRA}{?**?} &
+\cross{ALGEBRA}{?\^{}?} \\
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item {\bf \cross{ALGEBRA}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{ALGEBRA}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{ALGEBRA}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are implemented by this category:
+\begin{verbatim}
+ coerce : R -> %
+\end{verbatim}
+
+These exports come from \refto{Ring}():
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ characteristic : () -> NonNegativeInteger
+ coerce : Integer -> %                
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger            
+ latex : % -> String
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+These exports come from \refto{Module}(R:CommutativeRing):
+\begin{verbatim}
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+<<category ALGEBRA Algebra>>=
+)abbrev category ALGEBRA Algebra
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of associative algebras (modules which are themselves rings).
+++
+++ Axioms:
+++   \spad{(b+c)::% = (b::%) + (c::%)}
+++   \spad{(b*c)::% = (b::%) * (c::%)}
+++   \spad{(1::R)::% = 1::%}
+++   \spad{b*x = (b::%)*x}
+++   \spad{r*(a*b) = (r*a)*b = a*(r*b)}
+Algebra(R:CommutativeRing): Category ==
+  Join(Ring, Module R) with
+      coerce: R -> %
+          ++ coerce(r) maps the ring element r to a member of the algebra.
+ add
+  coerce(x:R):% == x * 1$%
+
+@
+<<ALGEBRA.dotabb>>=
+"ALGEBRA"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"ALGEBRA" -> "RING"
+"ALGEBRA" -> "MODULE"
+
+@
+<<ALGEBRA.dotfull>>=
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "Ring()"
+"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"Algebra(a:Field)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:Field)" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(Integer)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Integer)" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(IntegralDomain)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(IntegralDomain)" -> "Algebra(a:CommutativeRing)"
+
+@
+<<ALGEBRA.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"Algebra(a:CommutativeRing)" [color=lightblue];
+"Algebra(a:CommutativeRing)" -> "Ring()"
+"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"Ring()" [color=lightblue];
+"Ring()" -> "Rng()"
+"Ring()" -> "Monoid()"
+"Ring()" -> "LeftModule(a:Ring)"
+
+"Rng()" [color=lightblue];
+"Rng()" -> "ABELGRP..."
+"Rng()" -> "SemiGroup()"
+
+"SemiGroup()" [color=lightblue];
+"SemiGroup()" -> "SETCAT..."
+"SemiGroup()" -> "REPSQ..."
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SemiGroup()"
+
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"ABELGRP..." [color=lightblue];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{DifferentialExtension}{DIFEXT}
 \pagepic{ps/v102differentialextension.ps}{DIFEXT}{0.65}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{DifferentialPolynomialCategory}{DPOLCAT}
 \pageto{DirectProductCategory}{DIRPCAT}
+\pageto{QuaternionCategory}{QUATCAT}
 \pageto{QuotientFieldCategory}{QFCAT}
 \pageto{SquareMatrixCategory}{SMATCAT}
 \pageto{UnivariatePolynomialCategory}{UPOLYC}
@@ -28380,6 +30781,11 @@ DifferentialExtension(R:Ring): Category == Ring with
 "DifferentialExtension(IntegralDomain)" ->
   "DifferentialExtension(a:Ring)"
 
+"DifferentialExtension(CommutativeRing)" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=DIFEXT"];
+"DifferentialExtension(CommutativeRing)" ->
+  "DifferentialExtension(a:Ring)"
+
 @
 <<DIFEXT.dotpic>>=
 digraph pic {
@@ -28425,388 +30831,16 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{FiniteAbelianMonoidRing}{FAMR}
-\pagepic{ps/v102finiteabelianmonoidring.ps}{FAMR}{0.40}
-
-{\bf See:}\\
-\pageto{PolynomialCategory}{POLYCAT}
-\pagefrom{AbelianMonoidRing}{AMR}
-\pagefrom{FullyRetractableTo}{FRETRCT}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{FAMR}{0} &
-\cross{FAMR}{1} &
-\cross{FAMR}{associates?} &
-\cross{FAMR}{binomThmExpt} \\
-\cross{FAMR}{characteristic} &
-\cross{FAMR}{charthRoot} &
-\cross{FAMR}{coefficient} &
-\cross{FAMR}{coefficients} \\
-\cross{FAMR}{coerce} &
-\cross{FAMR}{content} &
-\cross{FAMR}{degree} &
-\cross{FAMR}{exquo} \\
-\cross{FAMR}{ground} &
-\cross{FAMR}{ground?} &
-\cross{FAMR}{hash} &
-\cross{FAMR}{latex} \\
-\cross{FAMR}{leadingCoefficient} &
-\cross{FAMR}{leadingMonomial} &
-\cross{FAMR}{map} &
-\cross{FAMR}{mapExponents} \\
-\cross{FAMR}{minimumDegree} &
-\cross{FAMR}{monomial} &
-\cross{FAMR}{monomial?} &
-\cross{FAMR}{numberOfMonomials} \\
-\cross{FAMR}{one?} &
-\cross{FAMR}{pomopo!} &
-\cross{FAMR}{primitivePart} &
-\cross{FAMR}{recip} \\
-\cross{FAMR}{reductum} &
-\cross{FAMR}{retract} &
-\cross{FAMR}{retractIfCan} &
-\cross{FAMR}{sample} \\
-\cross{FAMR}{subtractIfCan} &
-\cross{FAMR}{unit?} &
-\cross{FAMR}{unitCanonical} &
-\cross{FAMR}{unitNormal} \\
-\cross{FAMR}{zero?} &
-\cross{FAMR}{?*?} &
-\cross{FAMR}{?**?} &
-\cross{FAMR}{?+?} \\
-\cross{FAMR}{?-?} &
-\cross{FAMR}{-?} &
-\cross{FAMR}{?=?} &
-\cross{FAMR}{?\^{}?} \\
-\cross{FAMR}{?\~{}=?} &
-\cross{FAMR}{?/?} &&
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item if \$ has CommutativeRing then commutative(``*'') where
-{\bf \cross{FAMR}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
-\item if \$ has IntegralDomain then noZeroDivisors where
-{\bf \cross{FAMR}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item {\bf \cross{FAMR}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{FAMR}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{FAMR}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- minimumDegree : % -> E
- numberOfMonomials : % -> NonNegativeInteger
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- binomThmExpt : (%,%,NonNegativeInteger) -> % 
-     if R has COMRING
- coefficients : % -> List R           
- content : % -> R if R has GCDDOM
- exquo : (%,R) -> Union(%,"failed") if R has INTDOM
- ground : % -> R
- ground? : % -> Boolean               
- mapExponents : ((E -> E),%) -> %     
- pomopo! : (%,R,E,%) -> %
- primitivePart : % -> % if R has GCDDOM
- ?/? : (%,R) -> % if R has FIELD
-\end{verbatim}
-
-These exports come from \refto{AbelianMonoidRing}(R,E)\\
-where R:Ring and E:OrderedAbelianMonoid:
-\begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- associates? : (%,%) -> Boolean if R has INTDOM
- characteristic : () -> NonNegativeInteger
- charthRoot : % -> Union(%,"failed") if R has CHARNZ
- coefficient : (%,E) -> R
- coerce : R -> %
- coerce : Fraction Integer -> % 
-     if R has RETRACT FRAC INT 
-     or R has ALGEBRA FRAC INT
- coerce : % -> % if R has INTDOM
- coerce : % -> OutputForm
- coerce : Integer -> %                
- degree : % -> E                      
- exquo : (%,%) -> Union(%,"failed") if R has INTDOM
- hash : % -> SingleInteger
- latex : % -> String                  
- leadingCoefficient : % -> R
- leadingMonomial : % -> %             
- map : ((R -> R),%) -> %
- monomial : (R,E) -> %                
- monomial? : % -> Boolean
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")       
- reductum : % -> %
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- unit? : % -> Boolean if R has INTDOM
- unitCanonical : % -> % if R has INTDOM
- unitNormal :
-    % -> Record(unit: %,canonical: %,associate: %) 
-    if R has INTDOM
- zero? : % -> Boolean                 
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
- ?*? : (Fraction Integer,%) -> % if R has ALGEBRA FRAC INT
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (Integer,%) -> %
- ?*? : (%,%) -> %                     
- ?*? : (%,Fraction Integer) -> % if R has ALGEBRA FRAC INT
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
-\end{verbatim}
-
-These exports come from \refto{FullyRetractableTo}(R:Ring):
-\begin{verbatim}
- retract : % -> Fraction Integer 
-     if R has RETRACT FRAC INT
- retract : % -> Integer if R has RETRACT INT
- retract : % -> R                     
- retractIfCan : % -> Union(R,"failed")
- retractIfCan : % -> Union(Integer,"failed") 
-     if R has RETRACT INT
- retractIfCan : % -> Union(Fraction Integer,"failed") 
-     if R has RETRACT FRAC INT
-\end{verbatim}
-
-<<category FAMR FiniteAbelianMonoidRing>>=
-)abbrev category FAMR FiniteAbelianMonoidRing
-++ Author:
-++ Date Created:
-++ Date Last Updated: 14.08.2000 Exported pomopo! and binomThmExpt [MMM]
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description: This category is
-++ similar to AbelianMonoidRing, except that the sum is assumed to be finite.
-++ It is a useful model for polynomials,
-++ but is somewhat more general.
-
-FiniteAbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
-   Join(AbelianMonoidRing(R,E),FullyRetractableTo R) with
-    ground?: % -> Boolean
-      ++ ground?(p) tests if polynomial p is a member of the 
-      ++ coefficient ring.
-      -- can't be defined earlier, since a power series
-      -- might not know if there were other terms or not
-    ground: % -> R
-      ++ ground(p) retracts polynomial p to the coefficient ring.
-    coefficients: % -> List R
-      ++ coefficients(p) gives the list of non-zero coefficients 
-      ++ of polynomial p.
-    numberOfMonomials: % -> NonNegativeInteger
-      ++ numberOfMonomials(p) gives the number of non-zero monomials 
-      ++ in polynomial p.
-    minimumDegree: % -> E
-      ++ minimumDegree(p) gives the least exponent of a non-zero term 
-      ++ of polynomial p. Error: if applied to 0.
-    mapExponents: (E -> E, %) -> %
-      ++ mapExponents(fn,u) maps function fn onto the exponents
-      ++ of the non-zero monomials of polynomial u.
-    pomopo!: (%,R,E,%) -> %
-      ++ \spad{pomopo!(p1,r,e,p2)} returns \spad{p1 + monomial(e,r) * p2}
-      ++ and may use \spad{p1} as workspace. The constaant \spad{r} is
-      ++ assumed to be nonzero.
-    if R has CommutativeRing then
-       binomThmExpt: (%,%,NonNegativeInteger) -> %
-         ++ \spad{binomThmExpt(p,q,n)} returns \spad{(x+y)^n}
-         ++ by means of the binomial theorem trick.
-    if R has IntegralDomain then
-       "exquo": (%,R) -> Union(%,"failed")
-       ++ exquo(p,r) returns the exact quotient of polynomial p by r, 
-       ++ or "failed" if none exists.
-    if R has GcdDomain then
-       content: % -> R
-         ++ content(p) gives the gcd of the coefficients of polynomial p.
-       primitivePart: % -> %
-         ++ primitivePart(p) returns the unit normalized form of polynomial p
-         ++ divided by the content of p.
-  add
-    pomopo!(p1,r,e,p2) == p1 + r * mapExponents(#1+e,p2)
-
-    if R has CommutativeRing then 
-       binomThmExpt(x,y,nn) ==
-               nn = 0 => 1$%
-               ans,xn,yn: %
-               bincoef: Integer
-               powl: List(%):= [x]
-               for i in 2..nn repeat powl:=[x * powl.first, :powl]
-               yn:=y; ans:=powl.first; i:=1; bincoef:=nn
-               for xn in powl.rest repeat
-                  ans:= bincoef * xn * yn + ans
-                  bincoef:= (nn-i) * bincoef quo (i+1);  i:= i+1
-                  -- last I and BINCOEF unused
-                  yn:= y * yn
-               ans + yn
-    ground? x ==
-      retractIfCan(x)@Union(R,"failed") case "failed" => false
-      true
-
-    ground x == retract(x)@R
-
-    mapExponents (fn:E -> E, x: %) ==
-         -- this default definition assumes that reductum is cheap
-       zero? x => 0
-       monomial(leadingCoefficient x,fn degree x)+mapExponents(fn,reductum x)
-
-    coefficients x ==
-      zero? x => empty()
-      concat(leadingCoefficient x, coefficients reductum x)
-
-    if R has Field then
-       x/r == map(#1/r,x)
-
-    if R has IntegralDomain then
-       x exquo r ==
-          -- probably not a very good definition in most special cases
-          zero? x => 0
-          ans:% :=0
-          t:=leadingCoefficient x exquo r
-          while not (t case "failed") and not zero? x repeat
-            ans:=ans+monomial(t::R,degree x)
-            x:=reductum x
-            if not zero? x then t:=leadingCoefficient x exquo r
-          t case "failed" => "failed"
-          ans
-
-    if R has GcdDomain then
-       content x ==       -- this assumes  reductum is cheap
-          zero? x => 0
-          r:=leadingCoefficient x
-          x:=reductum x
---          while not zero? x and not one? r repeat
-          while not zero? x and not (r = 1) repeat
-            r:=gcd(r,leadingCoefficient x)
-            x:=reductum x
-          r
-
-       primitivePart x ==
-          zero? x => x
-          c := content x
-          unitCanonical((x exquo c)::%)
-
-@
-<<FAMR.dotabb>>=
-"FAMR"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=FAMR"];
-"FAMR" -> "AMR"
-"FAMR" -> "FRETRCT"
-
-@
-<<FAMR.dotfull>>=
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=FAMR"];
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
-    "FullyRetractableTo(a:Ring)"
-
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoidSup)" 
- [color=seagreen,href="bookvol10.2.pdf#nameddest=FAMR"];
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoidSup)" ->
-    "FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-
-@
-<<FAMR.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
-    "FullyRetractableTo(a:Ring)"
-
-"FullyRetractableTo(a:Ring)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=FRETRCT"];
-"FullyRetractableTo(a:Ring)" -> "FullyRetractableTo(a:Type)"
-
-"FullyRetractableTo(a:Type)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=FRETRCT"];
-"FullyRetractableTo(a:Type)" -> "RETRACT..."
-
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BIMODULE..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
-
-"IntegralDomain()" [color=lightblue];
-"IntegralDomain()" -> "CommutativeRing()"
-"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
-"IntegralDomain()" -> "EntireRing()"
-
-"EntireRing()" [color=lightblue];
-"EntireRing()" -> "RING..."
-"EntireRing()" -> "BIMODULE..."
-
-"CharacteristicNonZero()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
-"CharacteristicNonZero()" -> "RING..."
-
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
-
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "RING..."
-"Algebra(a:CommutativeRing)" -> "MODULE..."
-
-"CommutativeRing()" [color=lightblue];
-"CommutativeRing()" -> "RING..."
-"CommutativeRing()" -> "BIMODULE..."
-
-"RETRACT..." [color=lightblue];
-"BIMODULE..." [color=lightblue];
-"RING..." [color=lightblue];
-"MODULE..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FullyLinearlyExplicitRingOver}{FLINEXP}
 \pagepic{ps/v102fullylinearlyexplicitringover.ps}{FLINEXP}{1.00}
 
 {\bf See:}\\
+\pageto{ComplexCategory}{COMPCAT}
 \pageto{DirectProductCategory}{DIRPCAT}
 \pageto{FunctionSpace}{FS}
 \pageto{MonogenicAlgebra}{MONOGEN}
 \pageto{PolynomialCategory}{POLYCAT}
+\pageto{QuaternionCategory}{QUATCAT}
 \pageto{QuotientFieldCategory}{QFCAT}
 \pageto{SquareMatrixCategory}{SMATCAT}
 \pagefrom{LinearlyExplicitRingOver}{LINEXP}
@@ -28985,58 +31019,67 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{Module}{MODULE}
-\pagepic{ps/v102module.ps}{MODULE}{1.00}
+\pagehead{LieAlgebra}{LIECAT}
+\pagepic{ps/v102liealgebra.ps}{LIECAT}{1.00}
 
 {\bf See:}\\
-\pageto{Algebra}{ALGEBRA}
-\pageto{LieAlgebra}{LIECAT}
-\pageto{NonAssociativeAlgebra}{NAALG}
-\pageto{RectangularMatrixCategory}{RMATCAT}
-\pageto{VectorSpace}{VSPACE}
-\pagefrom{BiModule}{BMODULE}
+\pageto{FreeLieAlgebra}{FLALG}
+\pagefrom{Module}{MODULE}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{MODULE}{0} &
-\cross{MODULE}{coerce} &
-\cross{MODULE}{hash} &
-\cross{MODULE}{latex} &
-\cross{MODULE}{sample} \\
-\cross{MODULE}{subtractIfCan} &
-\cross{MODULE}{zero?} &
-\cross{MODULE}{?\~{}=?} &
-\cross{MODULE}{?*?} &
-\cross{MODULE}{?+?} \\
-\cross{MODULE}{?-?} &
-\cross{MODULE}{-?} &
-\cross{MODULE}{?=?} &&
+\cross{LIECAT}{0} &
+\cross{LIECAT}{coerce} &
+\cross{LIECAT}{construct} &
+\cross{LIECAT}{hash} &
+\cross{LIECAT}{latex} \\
+\cross{LIECAT}{sample} &
+\cross{LIECAT}{subtractIfCan} &
+\cross{LIECAT}{zero?} &
+\cross{LIECAT}{?\~{}=?} &
+\cross{LIECAT}{?/?} \\
+\cross{LIECAT}{?*?} &
+\cross{LIECAT}{?+?} &
+\cross{LIECAT}{?-?} &
+\cross{LIECAT}{-?} &
+\cross{LIECAT}{?=?} \\
 \end{tabular}
 
-{\bf Attributes exported:}
+{\bf Attributes Exported:}
 \begin{itemize}
-\item {\bf \cross{MODULE}{leftUnitary}}
+\item {\bf \cross{LIECAT}{NullSquare}}
+means that $[x,x] = 0$ holds. See {\tt LieAlgebra}.
+\item {\bf \cross{LIECAT}{JacobiIdentity}}
+means that $[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0$ holds.
+See {\tt LieAlgebra}.
+\item {\bf \cross{LIECAT}{leftUnitary}}
 is true if $1 * x = x$ for all x.
-\item {\bf \cross{MODULE}{rightUnitary}}
+\item {\bf \cross{LIECAT}{rightUnitary}}
 is true if $x * 1 = x$ for all x.
 \end{itemize}
 
+These are directly exported but not implemented:
+\begin{verbatim}
+ construct : (%,%) -> %               
+\end{verbatim}
+
 These are implemented by this category:
 \begin{verbatim}
- ?*? : (%,R) -> %                     
+ ?/? : (%,R) -> % if R has FIELD
 \end{verbatim}
 
-These exports come from \refto{BiModule}(a:Ring,b:Ring):
+These exports come from \refto{Module}(R:Ring):
 \begin{verbatim}
  0 : () -> %                          
  coerce : % -> OutputForm
- hash : % -> SingleInteger            
- latex : % -> String
- sample : () -> %                     
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ sample : () -> %
  subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean
- ?~=? : (%,%) -> Boolean              
+ zero? : % -> Boolean                 
+ ?~=? : (%,%) -> Boolean
  ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (%,R) -> %                     
  ?*? : (R,%) -> %
  ?*? : (Integer,%) -> %               
  ?*? : (PositiveInteger,%) -> %
@@ -29046,11 +31089,12 @@ These exports come from \refto{BiModule}(a:Ring,b:Ring):
  ?=? : (%,%) -> Boolean
 \end{verbatim}
 
-<<category MODULE Module>>=
-)abbrev category MODULE Module
-++ Author:
-++ Date Created:
-++ Date Last Updated:
+<<category LIECAT LieAlgebra>>=
+)abbrev category LIECAT LieAlgebra
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
 ++ Basic Functions:
 ++ Related Constructors:
 ++ Also See:
@@ -29058,41 +31102,48 @@ These exports come from \refto{BiModule}(a:Ring,b:Ring):
 ++ Keywords:
 ++ References:
 ++ Description:
-++ The category of modules over a commutative ring.
-++
-++ Axioms:
-++   \spad{1*x = x}
-++   \spad{(a*b)*x = a*(b*x)}
-++   \spad{(a+b)*x = (a*x)+(b*x)}
-++   \spad{a*(x+y) = (a*x)+(a*y)}
-Module(R:CommutativeRing): Category == BiModule(R,R)
+++ The category of Lie Algebras.
+++ It is used by the following domains of non-commutative algebra:
+++ \axiomType{LiePolynomial} and 
+++ \axiomType{XPBWPolynomial}. \newline 
+++ Author : Michel Petitot (petitot@lifl.fr).
+LieAlgebra(R: CommutativeRing): Category ==  Module(R) with
+    NullSquare 
+      ++ \axiom{NullSquare} means that \axiom{[x,x] = 0} holds.
+    JacobiIdentity 
+      ++ \axiom{JacobiIdentity} means that 
+      ++ \axiom{[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0} holds.
+    construct:  ($,$) -> $
+      ++ \axiom{construct(x,y)} returns the Lie bracket of \axiom{x} 
+      ++ and \axiom{y}.
+    if R has Field then 
+       "/"   :  ($,R) -> $
+         ++ \axiom{x/r} returns the division of \axiom{x} by \axiom{r}.
   add
-    if not(R is %) then x:%*r:R == r*x
+    if R has Field then x / r == inv(r)$R * x
 
 @
-<<MODULE.dotabb>>=
-"MODULE"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MODULE"];
-"MODULE" -> "BMODULE"
+<<LIECAT.dotabb>>=
+"LIECAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=LIECAT"];
+"LIECAT" -> "MODULE"
 
 @
-<<MODULE.dotfull>>=
-"Module(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MODULE"];
-"Module(a:CommutativeRing)" ->
-  "BiModule(a:CommutativeRing,b:CommutativeRing)"
-
-"Module(Field)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=MODULE"];
-"Module(Field)" -> "Module(a:CommutativeRing)"
+<<LIECAT.dotfull>>=
+"LieAlgebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=LIECAT"];
+"LieAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
 
 @
-<<MODULE.dotpic>>=
+<<LIECAT.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
+"LieAlgebra(a:CommutativeRing)" [color=lightblue];
+"LieAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
 "Module(a:CommutativeRing)" [color=lightblue];
 "Module(a:CommutativeRing)" ->
   "BiModule(a:CommutativeRing,b:CommutativeRing)"
@@ -29121,1098 +31172,640 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{MultivariateTaylorSeriesCategory}{MTSCAT}
-\pagepic{ps/v102multivariatetaylorseriescategory.ps}{MTSCAT}{1.00}
+\pagehead{LinearOrdinaryDifferentialOperatorCategory}{LODOCAT}
+\pagepic{ps/v102linearordinarydifferentialoperatorcategory.ps}{LODOCAT}{0.50}
 
 {\bf See:}\\
-\pagefrom{Evalable}{EVALAB}
-\pagefrom{InnerEvalable}{IEVALAB}
-\pagefrom{PartialDifferentialRing}{PDRING}
-\pagefrom{PowerSeriesCategory}{PSCAT}
+\pagefrom{Eltable}{ELTAB}
+\pagefrom{UnivariateSkewPolynomialCategory}{OREPCAT}
 
 {\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{MTSCAT}{0} &
-\cross{MTSCAT}{1} &
-\cross{MTSCAT}{acos} &
-\cross{MTSCAT}{acosh} &
-\cross{MTSCAT}{acot} \\
-\cross{MTSCAT}{acoth} &
-\cross{MTSCAT}{acsc} &
-\cross{MTSCAT}{acsch} &
-\cross{MTSCAT}{asec} &
-\cross{MTSCAT}{asech} \\
-\cross{MTSCAT}{asin} &
-\cross{MTSCAT}{asinh} &
-\cross{MTSCAT}{associates?} &
-\cross{MTSCAT}{atan} &
-\cross{MTSCAT}{atanh} \\
-\cross{MTSCAT}{characteristic} &
-\cross{MTSCAT}{charthRoot} &
-\cross{MTSCAT}{coefficient} &
-\cross{MTSCAT}{coerce} &
-\cross{MTSCAT}{complete} \\
-\cross{MTSCAT}{cos} &
-\cross{MTSCAT}{cosh} &
-\cross{MTSCAT}{cot} &
-\cross{MTSCAT}{coth} &
-\cross{MTSCAT}{csc} \\
-\cross{MTSCAT}{csch} &
-\cross{MTSCAT}{D} &
-\cross{MTSCAT}{degree} &
-\cross{MTSCAT}{differentiate} &
-\cross{MTSCAT}{eval} \\
-\cross{MTSCAT}{exp} &
-\cross{MTSCAT}{exquo} &
-\cross{MTSCAT}{extend} &
-\cross{MTSCAT}{hash} &
-\cross{MTSCAT}{integrate} \\
-\cross{MTSCAT}{latex} &
-\cross{MTSCAT}{leadingCoefficient} &
-\cross{MTSCAT}{leadingMonomial} &
-\cross{MTSCAT}{log} &
-\cross{MTSCAT}{map} \\
-\cross{MTSCAT}{monomial} &
-\cross{MTSCAT}{monomial?} &
-\cross{MTSCAT}{nthRoot} &
-\cross{MTSCAT}{order} &
-\cross{MTSCAT}{one?} \\
-\cross{MTSCAT}{pi} &
-\cross{MTSCAT}{pole?} &
-\cross{MTSCAT}{polynomial} &
-\cross{MTSCAT}{recip} &
-\cross{MTSCAT}{reductum} \\
-\cross{MTSCAT}{sample} &
-\cross{MTSCAT}{sec} &
-\cross{MTSCAT}{sech} &
-\cross{MTSCAT}{sin} &
-\cross{MTSCAT}{sinh} \\
-\cross{MTSCAT}{sqrt} &
-\cross{MTSCAT}{subtractIfCan} &
-\cross{MTSCAT}{tan} &
-\cross{MTSCAT}{tanh} &
-\cross{MTSCAT}{unit?} \\
-\cross{MTSCAT}{unitCanonical} &
-\cross{MTSCAT}{unitNormal} &
-\cross{MTSCAT}{variables} &
-\cross{MTSCAT}{zero?} &
-\cross{MTSCAT}{?*?} \\
-\cross{MTSCAT}{?**?} &
-\cross{MTSCAT}{?+?} &
-\cross{MTSCAT}{?-?} &
-\cross{MTSCAT}{-?} &
-\cross{MTSCAT}{?=?} \\
-\cross{MTSCAT}{?\^{}?} &
-\cross{MTSCAT}{?\~{}=?} &
-\cross{MTSCAT}{?/?} &&
+\begin{tabular}{lll}
+\cross{LODOCAT}{0} &
+\cross{LODOCAT}{1} &
+\cross{LODOCAT}{adjoint} \\
+\cross{LODOCAT}{apply} &
+\cross{LODOCAT}{characteristic} &
+\cross{LODOCAT}{coefficient} \\
+\cross{LODOCAT}{coefficients} &
+\cross{LODOCAT}{coerce} &
+\cross{LODOCAT}{content} \\
+\cross{LODOCAT}{D} &
+\cross{LODOCAT}{degree} &
+\cross{LODOCAT}{directSum} \\
+\cross{LODOCAT}{exquo} &
+\cross{LODOCAT}{hash} &
+\cross{LODOCAT}{latex} \\
+\cross{LODOCAT}{leadingCoefficient} &
+\cross{LODOCAT}{leftDivide} &
+\cross{LODOCAT}{leftExactQuotient} \\
+\cross{LODOCAT}{leftExtendedGcd} &
+\cross{LODOCAT}{leftGcd} &
+\cross{LODOCAT}{leftLcm} \\
+\cross{LODOCAT}{leftQuotient} &
+\cross{LODOCAT}{leftRemainder} &
+\cross{LODOCAT}{minimumDegree} \\
+\cross{LODOCAT}{monicLeftDivide} &
+\cross{LODOCAT}{monicRightDivide} &
+\cross{LODOCAT}{monomial} \\
+\cross{LODOCAT}{one?} &
+\cross{LODOCAT}{primitivePart} &
+\cross{LODOCAT}{recip} \\
+\cross{LODOCAT}{reductum} &
+\cross{LODOCAT}{retract} &
+\cross{LODOCAT}{retractIfCan} \\
+\cross{LODOCAT}{rightDivide} &
+\cross{LODOCAT}{rightExactQuotient} &
+\cross{LODOCAT}{rightExtendedGcd} \\
+\cross{LODOCAT}{rightGcd} &
+\cross{LODOCAT}{rightLcm} &
+\cross{LODOCAT}{rightQuotient} \\
+\cross{LODOCAT}{rightRemainder} &
+\cross{LODOCAT}{sample} &
+\cross{LODOCAT}{subtractIfCan} \\
+\cross{LODOCAT}{symmetricPower} &
+\cross{LODOCAT}{symmetricProduct} &
+\cross{LODOCAT}{symmetricSquare} \\
+\cross{LODOCAT}{zero?} &
+\cross{LODOCAT}{?\^{}?} &
+\cross{LODOCAT}{?.?} \\
+\cross{LODOCAT}{?\~{}=?} &
+\cross{LODOCAT}{?*?} &
+\cross{LODOCAT}{?**?} \\
+\cross{LODOCAT}{?+?} &
+\cross{LODOCAT}{?-?} &
+\cross{LODOCAT}{-?} \\
+\cross{LODOCAT}{?=?} &&
 \end{tabular}
 
 {\bf Attributes Exported:}
 \begin{itemize}
-\item if \$ has CommutativeRing then commutative(``*'') where
-{\bf \cross{MTSCAT}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
-\item if \$ has IntegralDomain then noZeroDivisors where
-{\bf \cross{MTSCAT}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item {\bf \cross{MTSCAT}{unitsKnown}}
+\item {\bf \cross{LODOCAT}{unitsKnown}}
 is true if a monoid (a multiplicative semigroup with a 1) has 
 unitsKnown means that  the operation {\tt recip} can only return 
 ``failed'' if its argument is not a unit.
-\item {\bf \cross{MTSCAT}{leftUnitary}}
+\item {\bf \cross{LODOCAT}{leftUnitary}}
 is true if $1 * x = x$ for all x.
-\item {\bf \cross{MTSCAT}{rightUnitary}}
+\item {\bf \cross{LODOCAT}{rightUnitary}}
 is true if $x * 1 = x$ for all x.
 \end{itemize}
 
 These are directly exported but not implemented:
 \begin{verbatim}
- coefficient : (%,Var,NonNegativeInteger) -> %
- coefficient : (%,List Var,List NonNegativeInteger) -> %
- extend : (%,NonNegativeInteger) -> %
- integrate : (%,Var) -> % if Coef has ALGEBRA FRAC INT
- monomial : (%,Var,NonNegativeInteger) -> %
- monomial : (%,List Var,List NonNegativeInteger) -> %
- order : (%,Var,NonNegativeInteger) -> NonNegativeInteger
- order : (%,Var) -> NonNegativeInteger
- polynomial : (%,NonNegativeInteger,NonNegativeInteger) -> Polynomial Coef
- polynomial : (%,NonNegativeInteger) -> Polynomial Coef
+ directSum : (%,%) -> % if A has FIELD
+ symmetricPower : (%,NonNegativeInteger) -> % if A has FIELD
+ symmetricProduct : (%,%) -> % if A has FIELD
 \end{verbatim}
 
-These exports come from \refto{PartialDifferentialRing}(OrderedSet):
+These are implemented by this category:
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
+ adjoint : % -> %                     
+ D : () -> %                          
+ symmetricSquare : % -> % if A has FIELD
+\end{verbatim}
+
+These exports come from \refto{UnivariateSkewPolynomialCategory}(A:Ring):
+\begin{verbatim}
+ 0 : () -> %                          
+ 1 : () -> %
+ apply : (%,A,A) -> A
  characteristic : () -> NonNegativeInteger
- coerce : Integer -> %
- coerce : % -> OutputForm             
- D : (%,Var) -> %
- D : (%,List Var) -> %                
- D : (%,List Var,List NonNegativeInteger) -> %
- D : (%,Var,NonNegativeInteger) -> %
- differentiate : (%,Var) -> %         
- differentiate : (%,List Var,List NonNegativeInteger) -> %
- differentiate : (%,Var,NonNegativeInteger) -> %
- differentiate : (%,List Var) -> %
- hash : % -> SingleInteger
- latex : % -> String                  
+ coefficient : (%,NonNegativeInteger) -> A
+ coefficients : % -> List A           
+ coerce : % -> OutputForm
+ coerce : Integer -> %                
+ coerce : A -> %
+ coerce : Fraction Integer -> % if A has RETRACT FRAC INT
+ content : % -> A if A has GCDDOM
+ degree : % -> NonNegativeInteger     
+ exquo : (%,A) -> Union(%,"failed") if A has INTDOM
+ hash : % -> SingleInteger            
+ latex : % -> String
+ leadingCoefficient : % -> A          
+ leftDivide : (%,%) -> Record(quotient: %,remainder: %) 
+    if A has FIELD
+ leftExactQuotient : (%,%) -> Union(%,"failed") if A has FIELD
+ leftExtendedGcd : (%,%) -> Record(coef1: %,coef2: %,generator: %) 
+    if A has FIELD
+ leftGcd : (%,%) -> % if A has FIELD
+ leftLcm : (%,%) -> % if A has FIELD
+ leftQuotient : (%,%) -> % if A has FIELD
+ leftRemainder : (%,%) -> % if A has FIELD
+ minimumDegree : % -> NonNegativeInteger
+ monicLeftDivide : (%,%) -> Record(quotient: %,remainder: %) 
+    if A has INTDOM
+ monicRightDivide : (%,%) -> Record(quotient: %,remainder: %) 
+    if A has INTDOM
+ monomial : (A,NonNegativeInteger) -> %
  one? : % -> Boolean
- recip : % -> Union(%,"failed")
+ primitivePart : % -> % if A has GCDDOM
+ recip : % -> Union(%,"failed")       
+ reductum : % -> %
+ retract : % -> A                     
+ retract : % -> Fraction Integer if A has RETRACT FRAC INT
+ retract : % -> Integer if A has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") 
+    if A has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") 
+    if A has RETRACT INT
+ retractIfCan : % -> Union(A,"failed")
+ rightDivide : (%,%) -> Record(quotient: %,remainder: %) 
+    if A has FIELD
+ rightExactQuotient : (%,%) -> Union(%,"failed") if A has FIELD
+ rightExtendedGcd :
+   (%,%) -> Record(coef1: %,coef2: %,generator: %) if A has FIELD
+ rightGcd : (%,%) -> % if A has FIELD
+ rightLcm : (%,%) -> % if A has FIELD
+ rightQuotient : (%,%) -> % if A has FIELD
+ rightRemainder : (%,%) -> % if A has FIELD
  sample : () -> %
  subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean
+ zero? : % -> Boolean                 
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
  ?+? : (%,%) -> %                     
+ ?*? : (%,A) -> %
+ ?*? : (A,%) -> %                     
+ ?~=? : (%,%) -> Boolean
  ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean              
- ?*? : (%,%) -> %                     
- ?*? : (Integer,%) -> %
- ?*? : (PositiveInteger,%) -> %       
  ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
  ?-? : (%,%) -> %
  -? : % -> %                          
- ?^? : (%,PositiveInteger) -> %       
- ?^? : (%,NonNegativeInteger) -> %
- ?**? : (%,NonNegativeInteger) -> %
  ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %
 \end{verbatim}
 
-These exports come from \refto{PowerSeriesCategory}(A,B,C)\\
-where A:Ring, B:IndexedExponents(OrderedSet) and C:OrderedSet:
-\begin{verbatim}
- associates? : (%,%) -> Boolean if Coef has INTDOM
- charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
- coefficient : (%,IndexedExponents Var) -> Coef
- coerce : Coef -> % if Coef has COMRING
- coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
- coerce : % -> % if Coef has INTDOM
- complete : % -> %
- degree : % -> IndexedExponents Var
- exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
- leadingCoefficient : % -> Coef
- leadingMonomial : % -> %             
- map : ((Coef -> Coef),%) -> %
- monomial : (Coef,IndexedExponents Var) -> %
- monomial? : % -> Boolean             
- monomial : (%,List Var,List IndexedExponents Var) -> %
- monomial : (%,Var,IndexedExponents Var) -> %
- pole? : % -> Boolean                 
- reductum : % -> %                    
- unit? : % -> Boolean if Coef has INTDOM
- unitCanonical : % -> % if Coef has INTDOM
- unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
-   if Coef has INTDOM
- variables : % -> List Var            
- ?*? : (%,Coef) -> %                  
- ?*? : (Coef,%) -> %
- ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
- ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
- ?/? : (%,Coef) -> % if Coef has FIELD
-\end{verbatim}
-
-These exports come from \refto{InnerEvalable}(OrderedSet,%):
+These exports come from \refto{Eltable}(A:Ring,A:Ring):
 \begin{verbatim}
- eval : (%,Var,%) -> %                
- eval : (%,List Var,List %) -> %
+ ?.? : (%,A) -> A
 \end{verbatim}
 
-These exports come from \refto{Evalable}(%):
-\begin{verbatim}
- eval : (%,List Equation %) -> %      
- eval : (%,Equation %) -> %
- eval : (%,List %,List %) -> %
- eval : (%,%,%) -> %                  
-\end{verbatim}
+<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>=
+)abbrev category LODOCAT LinearOrdinaryDifferentialOperatorCategory
+++ Author: Manuel Bronstein
+++ Date Created: 9 December 1993
+++ Date Last Updated: 15 April 1994
+++ Keywords: differential operator
+++ Description:
+++   \spad{LinearOrdinaryDifferentialOperatorCategory} is the category
+++   of differential operators with coefficients in a ring A with a given
+++   derivation.
+++   Multiplication of operators corresponds to functional composition:
+++       \spad{(L1 * L2).(f) = L1 L2 f}
+LinearOrdinaryDifferentialOperatorCategory(A:Ring): Category ==
+  Join(UnivariateSkewPolynomialCategory A, Eltable(A, A)) with
+        D: () -> %
+            ++ D() provides the operator corresponding to a derivation
+            ++ in the ring \spad{A}.
+        adjoint: % -> %
+            ++ adjoint(a) returns the adjoint operator of a.
+        if A has Field then
+          symmetricProduct: (%, %) -> %
+            ++ symmetricProduct(a,b) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the products of a solution of \spad{a} by
+            ++ a solution of \spad{b}.
+          symmetricPower  : (%, NonNegativeInteger) -> %
+            ++ symmetricPower(a,n) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the products of \spad{n} solutions
+            ++ of \spad{a}.
+          symmetricSquare : % -> %
+            ++ symmetricSquare(a) computes \spad{symmetricProduct(a,a)}
+            ++ using a more efficient method.
+          directSum: (%, %) -> %
+            ++ directSum(a,b) computes an operator \spad{c} of
+            ++ minimal order such that the nullspace of \spad{c} is
+            ++ generated by all the sums of a solution of \spad{a} by
+            ++ a solution of \spad{b}.
+   add
+        m1monom: NonNegativeInteger -> %
 
-These exports come from \refto{RadicalCategory}():
-\begin{verbatim}
- nthRoot : (%,Integer) -> % if Coef has ALGEBRA FRAC INT
- sqrt : % -> % if Coef has ALGEBRA FRAC INT
- ?**? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
-\end{verbatim}
+        D() == monomial(1, 1)
 
-These exports come from \refto{TranscendentalFunctionCategory}():
-\begin{verbatim}
- acos : % -> % if Coef has ALGEBRA FRAC INT
- acosh : % -> % if Coef has ALGEBRA FRAC INT
- acot : % -> % if Coef has ALGEBRA FRAC INT
- acoth : % -> % if Coef has ALGEBRA FRAC INT
- acsc : % -> % if Coef has ALGEBRA FRAC INT
- acsch : % -> % if Coef has ALGEBRA FRAC INT
- asec : % -> % if Coef has ALGEBRA FRAC INT
- asech : % -> % if Coef has ALGEBRA FRAC INT
- asin : % -> % if Coef has ALGEBRA FRAC INT
- asinh : % -> % if Coef has ALGEBRA FRAC INT
- atan : % -> % if Coef has ALGEBRA FRAC INT
- atanh : % -> % if Coef has ALGEBRA FRAC INT
- cos : % -> % if Coef has ALGEBRA FRAC INT
- cosh : % -> % if Coef has ALGEBRA FRAC INT
- cot : % -> % if Coef has ALGEBRA FRAC INT
- coth : % -> % if Coef has ALGEBRA FRAC INT
- csc : % -> % if Coef has ALGEBRA FRAC INT
- csch : % -> % if Coef has ALGEBRA FRAC INT
- exp : % -> % if Coef has ALGEBRA FRAC INT
- log : % -> % if Coef has ALGEBRA FRAC INT
- pi : () -> % if Coef has ALGEBRA FRAC INT
- sec : % -> % if Coef has ALGEBRA FRAC INT
- sech : % -> % if Coef has ALGEBRA FRAC INT
- sin : % -> % if Coef has ALGEBRA FRAC INT
- sinh : % -> % if Coef has ALGEBRA FRAC INT
- tan : % -> % if Coef has ALGEBRA FRAC INT
- tanh : % -> % if Coef has ALGEBRA FRAC INT
- ?**? : (%,%) -> % if Coef has ALGEBRA FRAC INT
-\end{verbatim}
+        m1monom n ==
+          a:A := (odd? n => -1; 1)
+          monomial(a, n)
 
-<<category MTSCAT MultivariateTaylorSeriesCategory>>=
-)abbrev category MTSCAT MultivariateTaylorSeriesCategory
-++ Author: Clifton J. Williamson
-++ Date Created: 6 March 1990
-++ Date Last Updated: 6 March 1990
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: multivariate, Taylor, series
-++ Examples:
-++ References:
-++ Description:
-++   \spadtype{MultivariateTaylorSeriesCategory} is the most general
-++   multivariate Taylor series category.
-MultivariateTaylorSeriesCategory(Coef,Var): Category == Definition where
-  Coef  : Ring
-  Var   : OrderedSet
-  L   ==> List
-  NNI ==> NonNegativeInteger
+        adjoint a ==
+          ans:% := 0
+          while a ^= 0 repeat
+            ans := ans + m1monom(degree a) * leadingCoefficient(a)::%
+            a   := reductum a
+          ans
 
-  Definition ==> Join(PartialDifferentialRing Var,_
-                     PowerSeriesCategory(Coef,IndexedExponents Var,Var),_
-                     InnerEvalable(Var,%),Evalable %) with
-    coefficient: (%,Var,NNI) -> %
-      ++ \spad{coefficient(f,x,n)} returns the coefficient of \spad{x^n} in f.
-    coefficient: (%,L Var,L NNI) -> %
-      ++ \spad{coefficient(f,[x1,x2,...,xk],[n1,n2,...,nk])} returns the
-      ++ coefficient of \spad{x1^n1 * ... * xk^nk} in f.
-    extend: (%,NNI) -> %
-      ++ \spad{extend(f,n)} causes all terms of f of degree
-      ++ \spad{<= n} to be computed.
-    monomial: (%,Var,NNI) -> %
-      ++ \spad{monomial(a,x,n)} returns  \spad{a*x^n}.
-    monomial: (%,L Var,L NNI) -> %
-      ++ \spad{monomial(a,[x1,x2,...,xk],[n1,n2,...,nk])} returns
-      ++ \spad{a * x1^n1 * ... * xk^nk}.
-    order: (%,Var) -> NNI
-      ++ \spad{order(f,x)} returns the order of f viewed as a series in x
-      ++ may result in an infinite loop if f has no non-zero terms.
-    order: (%,Var,NNI) -> NNI
-      ++ \spad{order(f,x,n)} returns \spad{min(n,order(f,x))}.
-    polynomial: (%,NNI) -> Polynomial Coef
-      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
-      ++ of all terms of f of degree \spad{<= k}.
-    polynomial: (%,NNI,NNI) -> Polynomial Coef
-      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
-      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
-    if Coef has Algebra Fraction Integer then
-      integrate: (%,Var) -> %
-        ++ \spad{integrate(f,x)} returns the anti-derivative of the power
-        ++ series \spad{f(x)} with respect to the variable x with constant
-        ++ coefficient 1.  We may integrate a series when we can divide
-        ++ coefficients by integers.
-      RadicalCategory
-        --++ We provide rational powers when we can divide coefficients
-        --++ by integers.
-      TranscendentalFunctionCategory
-        --++ We provide transcendental functions when we can divide
-        --++ coefficients by integers.
+        if A has Field then symmetricSquare l == symmetricPower(l, 2)
 
 @
-<<MTSCAT.dotabb>>=
-"MTSCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MTSCAT"];
-"MTSCAT" -> "PDRING"
-"MTSCAT" -> "PSCAT"
-"MTSCAT" -> "IEVALAB"
-"MTSCAT" -> "EVALAB"
+<<LODOCAT.dotabb>>=
+"LODOCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=LODOCAT"];
+"LODOCAT" -> "ELTAB"
+"LODOCAT" -> "OREPCAT"
 
 @
-<<MTSCAT.dotfull>>=
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MTSCAT"];
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
-    "PartialDifferentialRing(a:OrderedSet)"
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
-   "PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
- "InnerEvalable(a:Ring,MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet))"
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
- "Evalable(MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet))"
+<<LODOCAT.dotfull>>=
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=LODOCAT"];
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)"
+  -> "Eltable(a:Ring,b:Ring)"
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)"
+  -> "UnivariateSkewPolynomialCategory(R:Ring)"
 
 @
-<<MTSCAT.dotpic>>=
+<<LODOCAT.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" [color=lightblue];
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
-    "PDRING..."
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
-   "PSCAT..."
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
- "IEVALAB..."
-"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
- "EVALAB..."
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)" [color=lightblue];
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)"
+  -> "Eltable(a:Ring,b:Ring)"
+"LinearOrdinaryDifferentialOperatorCategory(a:Ring)"
+  -> "UnivariateSkewPolynomialCategory(R:Ring)"
 
-"PDRING..." [color=lightblue];
-"PSCAT..." [color=lightblue];
-"IEVALAB..." [color=lightblue];
-"EVALAB..." [color=lightblue];
+"Eltable(a:Ring,b:Ring)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ELTAB"];
+"Eltable(a:Ring,b:Ring)" ->
+   "Eltable(a:SetCategory,b:Type)" 
+
+"Eltable(a:SetCategory,b:Type)" [color=lightblue];
+"Eltable(a:SetCategory,b:Type)" -> "Category"
+
+"UnivariateSkewPolynomialCategory(R:Ring)" [color=lightblue];
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "BiModule(a:Ring,b:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "FullyRetractableTo(a:Ring)"
+"UnivariateSkewPolynomialCategory(R:Ring)"
+  -> "Ring()"
+
+"FullyRetractableTo(a:Ring)" [color=seagreen];
+"FullyRetractableTo(a:Ring)" -> "FullyRetractableTo(a:Type)"
+
+"FullyRetractableTo(a:Type)" [color=lightblue];
+"FullyRetractableTo(a:Type)" -> "RetractableTo(a:Type)"
+
+"RetractableTo(a:Type)" [color=lightblue];
+"RetractableTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+"Ring()" [color=lightblue];
+"Ring()" -> "Rng()"
+"Ring()" -> "Monoid()"
+"Ring()" -> "LeftModule(a:Ring)"
+
+"Rng()" [color=lightblue];
+"Rng()" -> "AbelianGroup()"
+"Rng()" -> "SemiGroup()"
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SemiGroup()"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "AbelianGroup()"
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "AbelianGroup()"
+
+"AbelianGroup()" [color=lightblue];
+"AbelianGroup()" -> "CABMON..."
+"AbelianGroup()" -> "REPDB..."
 
+"SemiGroup()" [color=lightblue];
+"SemiGroup()" -> "SETCAT..."
+"SemiGroup()" -> "REPSQ..."
+
+"REPDB..." [color="#00EE00"];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"CABMON..." [color=lightblue];
 }
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{UnivariatePowerSeriesCategory}{UPSCAT}
-\pagepic{ps/v102univariatepowerseriescategory.ps}{UPSCAT}{0.55}
+\pagehead{NonAssociativeAlgebra}{NAALG}
+\pagepic{ps/v102nonassociativealgebra.ps}{NAALG}{0.75}
 
 {\bf See:}\\
-\pageto{UnivariateLaurentSeriesCategory}{ULSCAT}
-\pageto{UnivariatePuiseuxSeriesCategory}{UPXSCAT}
-\pageto{UnivariateTaylorSeriesCategory}{UTSCAT}
-\pagefrom{PowerSeriesCategory}{PSCAT}
+\pageto{FiniteRankNonAssociativeAlgebra}{FINAALG}
+\pagefrom{Module}{MODULE}
+\pagefrom{NonAssociativeRng}{NARNG}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{UPSCAT}{0} &
-\cross{UPSCAT}{1} &
-\cross{UPSCAT}{approximate} &
-\cross{UPSCAT}{associates?} &
-\cross{UPSCAT}{center} \\
-\cross{UPSCAT}{characteristic} &
-\cross{UPSCAT}{charthRoot} &
-\cross{UPSCAT}{coefficient} &
-\cross{UPSCAT}{coerce} &
-\cross{UPSCAT}{complete} \\
-\cross{UPSCAT}{D} &
-\cross{UPSCAT}{degree} &
-\cross{UPSCAT}{differentiate} &
-\cross{UPSCAT}{eval} &
-\cross{UPSCAT}{exquo} \\
-\cross{UPSCAT}{extend} &
-\cross{UPSCAT}{hash} &
-\cross{UPSCAT}{latex} &
-\cross{UPSCAT}{leadingCoefficient} &
-\cross{UPSCAT}{leadingMonomial} \\
-\cross{UPSCAT}{map} &
-\cross{UPSCAT}{monomial} &
-\cross{UPSCAT}{monomial?} &
-\cross{UPSCAT}{multiplyExponents} &
-\cross{UPSCAT}{one?} \\
-\cross{UPSCAT}{order} &
-\cross{UPSCAT}{pole?} &
-\cross{UPSCAT}{recip} &
-\cross{UPSCAT}{reductum} &
-\cross{UPSCAT}{sample} \\
-\cross{UPSCAT}{subtractIfCan} &
-\cross{UPSCAT}{truncate} &
-\cross{UPSCAT}{terms} &
-\cross{UPSCAT}{unit?} &
-\cross{UPSCAT}{unitCanonical} \\
-\cross{UPSCAT}{unitNormal} &
-\cross{UPSCAT}{variable} &
-\cross{UPSCAT}{variables} &
-\cross{UPSCAT}{zero?} &
-\cross{UPSCAT}{?*?} \\
-\cross{UPSCAT}{?**?} &
-\cross{UPSCAT}{?+?} &
-\cross{UPSCAT}{?-?} &
-\cross{UPSCAT}{-?} &
-\cross{UPSCAT}{?=?} \\
-\cross{UPSCAT}{?\^{}?} &
-\cross{UPSCAT}{?.?} &
-\cross{UPSCAT}{?\~{}=?} &
-\cross{UPSCAT}{?/?} &
-\cross{UPSCAT}{?.?} \\
+\cross{NAALG}{0} &
+\cross{NAALG}{antiCommutator} &
+\cross{NAALG}{associator} &
+\cross{NAALG}{coerce} &
+\cross{NAALG}{commutator} \\
+\cross{NAALG}{hash} &
+\cross{NAALG}{latex} &
+\cross{NAALG}{leftPower} &
+\cross{NAALG}{plenaryPower} &
+\cross{NAALG}{rightPower} \\
+\cross{NAALG}{sample} &
+\cross{NAALG}{subtractIfCan} &
+\cross{NAALG}{zero?} &
+\cross{NAALG}{?\~{}=?} &
+\cross{NAALG}{?*?} \\
+\cross{NAALG}{?**?} &
+\cross{NAALG}{?+?} &
+\cross{NAALG}{?-?} &
+\cross{NAALG}{-?} &
+\cross{NAALG}{?=?} \\
 \end{tabular}
 
-{\bf Attributes Exported:}
+{\bf Attributes exported:}
 \begin{itemize}
-\item {\bf \cross{UPSCAT}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{UPSCAT}{leftUnitary}}
+\item {\bf \cross{NAALG}{leftUnitary}}
 is true if $1 * x = x$ for all x.
-\item {\bf \cross{UPSCAT}{rightUnitary}}
+\item {\bf \cross{NAALG}{rightUnitary}}
 is true if $x * 1 = x$ for all x.
-\item if \#1 has IntegralDomain then noZeroDivisors where
-{\bf \cross{UPSCAT}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item if \#1 has CommutativeRing then commutative(``*'') where
-{\bf \cross{UPSCAT}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
 \end{itemize}
 
-These are directly exported but not implemented:
-\begin{verbatim}
- approximate : (%,Expon) -> Coef 
-     if Coef has **: (Coef,Expon) -> Coef 
-     and Coef has coerce: Symbol -> Coef
- center : % -> Coef
- eval : (%,Coef) -> Stream Coef if Coef has **: (Coef,Expon) -> Coef
- extend : (%,Expon) -> %              
- multiplyExponents : (%,PositiveInteger) -> %
- order : % -> Expon                   
- order : (%,Expon) -> Expon
- terms : % -> Stream Record(k: Expon,c: Coef)
- truncate : (%,Expon) -> %            
- truncate : (%,Expon,Expon) -> %
- variable : % -> Symbol
- ?.? : (%,Expon) -> Coef
-\end{verbatim}
-
 These are implemented by this category:
 \begin{verbatim}
- degree : % -> Expon                  
- leadingCoefficient : % -> Coef
- leadingMonomial : % -> %             
- monomial : (%,SingletonAsOrderedSet,Expon) -> %
- reductum : % -> %
- variables : % -> List SingletonAsOrderedSet
+ plenaryPower : (%,PositiveInteger) -> %
 \end{verbatim}
 
-These exports come from \refto{PowerSeriesCategory}(C,E,S)\\
-where C:Ring, E:OrderedAbelianMonoid, S:SingletonAsOrderedSet:\\
+These exports come from \refto{NonAssociativeRng}():
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- associates? : (%,%) -> Boolean if Coef has INTDOM
- characteristic : () -> NonNegativeInteger
- charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
- coefficient : (%,Expon) -> Coef      
- coerce : Coef -> % if Coef has COMRING
- coerce : % -> % if Coef has INTDOM
- coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
- coerce : Integer -> %
- coerce : % -> OutputForm             
- complete : % -> %
- exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ 0 : () -> %                          
+ antiCommutator : (%,%) -> %
+ associator : (%,%,%) -> %            
+ coerce : % -> OutputForm
+ commutator : (%,%) -> %              
  hash : % -> SingleInteger
  latex : % -> String                  
- map : ((Coef -> Coef),%) -> %
- monomial : (%,List Var,List Expon) -> %
- monomial : (Coef,Expon) -> %         
- monomial? : % -> Boolean
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")       
- pole? : % -> Boolean
- sample : () -> %                     
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ sample : () -> %
  subtractIfCan : (%,%) -> Union(%,"failed")
- unit? : % -> Boolean if Coef has INTDOM
- unitCanonical : % -> % if Coef has INTDOM
- unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
-     if Coef has INTDOM
  zero? : % -> Boolean                 
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
+ ?~=? : (%,%) -> Boolean
+ ?*? : (PositiveInteger,%) -> %       
  ?+? : (%,%) -> %                     
  ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
+ ?*? : (Integer,%) -> %
  ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (%,%) -> %                     
  ?-? : (%,%) -> %
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
- ?*? : (Integer,%) -> %
- ?*? : (Coef,%) -> %                  
- ?*? : (%,Coef) -> %
- ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
- ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
- ?/? : (%,Coef) -> % if Coef has FIELD
  -? : % -> %                          
+ ?*? : (%,%) -> %                     
+ ?**? : (%,PositiveInteger) -> %
 \end{verbatim}
 
-These exports come from \refto{Eltable}(\%,\%):
-\begin{verbatim}
- ?.? : (%,%) -> % if Expon has SGROUP
-\end{verbatim}
-
-These exports come from \refto{DifferentialRing}():
-\begin{verbatim}
- D : % -> % 
-     if Coef has *: (Expon,Coef) -> Coef
- D : (%,NonNegativeInteger) -> % 
-     if Coef has *: (Expon,Coef) -> Coef
- differentiate : (%,NonNegativeInteger) -> % 
-     if Coef has *: (Expon,Coef) -> Coef
- differentiate : % -> % 
-     if Coef has *: (Expon,Coef) -> Coef
-\end{verbatim}
-
-These exports come from \refto{PartialDifferentialRing}(Symbol):
+These exports come from \refto{Module}(R:CommutativeRing):
 \begin{verbatim}
- D : (%,Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- D : (%,List Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- D : (%,Symbol,NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- D : (%,List Symbol,List NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- differentiate : (%,List Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- differentiate : (%,Symbol,NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
- differentiate : (%,Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (Expon,Coef) -> Coef
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
 \end{verbatim}
 
-<<category UPSCAT UnivariatePowerSeriesCategory>>=
-)abbrev category UPSCAT UnivariatePowerSeriesCategory
-++ Author: Clifton J. Williamson
-++ Date Created: 21 December 1989
-++ Date Last Updated: 20 September 1993
-++ Basic Operations:
-++ Related Domains:
+<<category NAALG NonAssociativeAlgebra>>=
+)abbrev category NAALG NonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +, -, *, **
+++ Related Constructors: Algebra
 ++ Also See:
 ++ AMS Classifications:
-++ Keywords:
-++ Examples:
-++ References:
+++ Keywords: nonassociative algebra
+++ Reference:
+++  R.D. Schafer: An Introduction to Nonassociative Algebras
+++  Academic Press, New York, 1966
 ++ Description:
-++   \spadtype{UnivariatePowerSeriesCategory} is the most general
-++   univariate power series category with exponents in an ordered
-++   abelian monoid.
-++   Note: this category exports a substitution function if it is
-++   possible to multiply exponents.
-++   Note: this category exports a derivative operation if it is possible
-++   to multiply coefficients by exponents.
-UnivariatePowerSeriesCategory(Coef,Expon): Category == Definition where
-  Coef   : Ring
-  Expon  : OrderedAbelianMonoid
-  Term ==> Record(k:Expon,c:Coef)
-
-  Definition ==> PowerSeriesCategory(Coef,Expon,SingletonAsOrderedSet) with
-
-    terms: % -> Stream Term
-      ++ \spad{terms(f(x))} returns a stream of non-zero terms, where a
-      ++ a term is an exponent-coefficient pair.  The terms in the stream
-      ++ are ordered by increasing order of exponents.
-    --series: Stream Term -> %
-      --++ \spad{series(st)} creates a series from a stream of non-zero terms,
-      --++ where a term is an exponent-coefficient pair.  The terms in the
-      --++ stream should be ordered by increasing order of exponents.
-    elt: (%,Expon) -> Coef
-      ++ \spad{elt(f(x),r)} returns the coefficient of the term of degree r in
-      ++ \spad{f(x)}.  This is the same as the function \spadfun{coefficient}.
-    variable: % -> Symbol
-      ++ \spad{variable(f)} returns the (unique) power series variable of
-      ++ the power series f.
-    center: % -> Coef
-      ++ \spad{center(f)} returns the point about which the series f is
-      ++ expanded.
-    multiplyExponents: (%,PositiveInteger) -> %
-      ++ \spad{multiplyExponents(f,n)} multiplies all exponents of the power
-      ++ series f by the positive integer n.
-    order: % -> Expon
-      ++ \spad{order(f)} is the degree of the lowest order non-zero term in f.
-      ++ This will result in an infinite loop if f has no non-zero terms.
-    order: (%,Expon) -> Expon
-      ++ \spad{order(f,n) = min(m,n)}, where m is the degree of the
-      ++ lowest order non-zero term in f.
-    truncate: (%,Expon) -> %
-      ++ \spad{truncate(f,k)} returns a (finite) power series consisting of
-      ++ the sum of all terms of f of degree \spad{<= k}.
-    truncate: (%,Expon,Expon) -> %
-      ++ \spad{truncate(f,k1,k2)} returns a (finite) power
-      ++ series consisting of
-      ++ the sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
-    if Coef has coerce: Symbol -> Coef then
-      if Coef has "**":(Coef,Expon) -> Coef then
-        approximate: (%,Expon) -> Coef
-          ++ \spad{approximate(f)} returns a truncated power series with the
-          ++ series variable viewed as an element of the coefficient domain.
-    extend: (%,Expon) -> %
-      ++ \spad{extend(f,n)} causes all terms of f of degree <= n 
-      ++ to be computed.
-    if Expon has SemiGroup then Eltable(%,%)
-    if Coef has "*": (Expon,Coef) -> Coef then
-      DifferentialRing
-      --!! DifferentialExtension Coef
-      if Coef has PartialDifferentialRing Symbol then
-        PartialDifferentialRing Symbol
-    if Coef has "**": (Coef,Expon) -> Coef then
-      eval: (%,Coef) -> Stream Coef
-        ++ \spad{eval(f,a)} evaluates a power series at a value in the
-        ++ ground ring by returning a stream of partial sums.
-
-   add
-    degree f == order f
-
-    leadingCoefficient f == coefficient(f,order f)
-
-    leadingMonomial f ==
-      ord := order f
-      monomial(coefficient(f,ord),ord)
-
-    monomial(f:%,listVar:List SingletonAsOrderedSet,listExpon:List Expon) ==
-      empty? listVar or not empty? rest listVar =>
-        error "monomial: variable list must have exactly one entry"
-      empty? listExpon or not empty? rest listExpon =>
-        error "monomial: exponent list must have exactly one entry"
-      f * monomial(1,first listExpon)
-
-    monomial(f:%,v:SingletonAsOrderedSet,n:Expon) ==
-      f * monomial(1,n)
-
-    reductum f == f - leadingMonomial f
-
-    variables f == list create()
+++   NonAssociativeAlgebra is the category of non associative algebras
+++   (modules which are themselves non associative rngs).
+++   Axioms
+++      r*(a*b) = (r*a)*b = a*(r*b)
+NonAssociativeAlgebra(R:CommutativeRing): Category == _
+  Join(NonAssociativeRng, Module R) with
+    plenaryPower : (%,PositiveInteger) -> %
+      ++ plenaryPower(a,n) is recursively defined to be
+      ++ \spad{plenaryPower(a,n-1)*plenaryPower(a,n-1)} for \spad{n>1}
+      ++ and \spad{a} for \spad{n=1}.
+  add
+    plenaryPower(a,n) ==
+--      one? n => a
+      ( n = 1 ) => a
+      n1 : PositiveInteger := (n-1)::NonNegativeInteger::PositiveInteger
+      plenaryPower(a,n1) * plenaryPower(a,n1)
 
 @
-<<UPSCAT.dotabb>>=
-"UPSCAT" 
- [color=lightblue,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UPSCAT" -> "PSCAT"
+<<NAALG.dotabb>>=
+"NAALG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
+"NAALG" -> "NARNG"
+"NAALG" -> "MODULE"
 
 @
-<<UPSCAT.dotfull>>=
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
- [color=lightblue,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
- "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
-
-"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" 
- [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" -> 
-    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
-
-"UnivariatePowerSeriesCategory(a:Ring,Integer)" 
- [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UnivariatePowerSeriesCategory(a:Ring,Integer)" -> 
-    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
-
-"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" 
- [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" ->
-    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+<<NAALG.dotfull>>=
+"NonAssociativeAlgebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
 
 @
-<<UPSCAT.dotpic>>=
+<<NAALG.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
- [color=lightblue];
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
- "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+"NonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
 
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
- [color=seagreen];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
-  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "ABELGRP..."
+"NonAssociativeRng()" -> "Monad()"
 
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
- [color=lightblue];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
 
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BIMODULE..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
 
-"IntegralDomain()" [color=lightblue];
-"IntegralDomain()" -> "CommutativeRing()"
-"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
-"IntegralDomain()" -> "EntireRing()"
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
 
-"EntireRing()" [color=lightblue];
-"EntireRing()" -> "RING..."
-"EntireRing()" -> "BIMODULE..."
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
 
-"CharacteristicNonZero()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
-"CharacteristicNonZero()" -> "RING..."
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
 
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
 
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "RING..."
-"Algebra(a:CommutativeRing)" -> "MODULE..."
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
 
-"CommutativeRing()" [color=lightblue];
-"CommutativeRing()" -> "RING..."
-"CommutativeRing()" -> "BIMODULE..."
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
 
-"BIMODULE..." [color=lightblue];
-"RING..." [color=lightblue];
-"MODULE..." [color=lightblue];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
 }
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{VectorCategory}{VECTCAT}
-\pagepic{ps/v102vectorcategory.ps}{VECTCAT}{1.00}
+\pagehead{VectorSpace}{VSPACE}
+\pagepic{ps/v102vectorspace.ps}{VSPACE}{1.00}
 
 {\bf See:}\\
-\pageto{PointCategory}{PTCAT}
-\pagefrom{OneDimensionalArrayAggregate}{A1AGG}
+\pageto{ExtensionField}{XF}
+\pagefrom{Module}{MODULE}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{VECTCAT}{any?} &
-\cross{VECTCAT}{coerce} &
-\cross{VECTCAT}{concat} &
-\cross{VECTCAT}{construct} &
-\cross{VECTCAT}{convert} \\
-\cross{VECTCAT}{copy} &
-\cross{VECTCAT}{copyInto!} &
-\cross{VECTCAT}{count} &
-\cross{VECTCAT}{cross} &
-\cross{VECTCAT}{delete} \\
-\cross{VECTCAT}{dot} &
-\cross{VECTCAT}{entry?} &
-\cross{VECTCAT}{elt} &
-\cross{VECTCAT}{empty} &
-\cross{VECTCAT}{empty?} \\
-\cross{VECTCAT}{entries} &
-\cross{VECTCAT}{eq?} &
-\cross{VECTCAT}{eval} &
-\cross{VECTCAT}{every?} &
-\cross{VECTCAT}{fill!} \\
-\cross{VECTCAT}{find} &
-\cross{VECTCAT}{first} &
-\cross{VECTCAT}{hash} &
-\cross{VECTCAT}{index?} &
-\cross{VECTCAT}{indices} \\
-\cross{VECTCAT}{insert} &
-\cross{VECTCAT}{latex} &
-\cross{VECTCAT}{length} &
-\cross{VECTCAT}{less?} &
-\cross{VECTCAT}{magnitude} \\
-\cross{VECTCAT}{map} &
-\cross{VECTCAT}{map!} &
-\cross{VECTCAT}{max} &
-\cross{VECTCAT}{maxIndex} &
-\cross{VECTCAT}{member?} \\
-\cross{VECTCAT}{members} &
-\cross{VECTCAT}{merge} &
-\cross{VECTCAT}{min} &
-\cross{VECTCAT}{minIndex} &
-\cross{VECTCAT}{more?} \\
-\cross{VECTCAT}{new} &
-\cross{VECTCAT}{outerProduct} &
-\cross{VECTCAT}{parts} &
-\cross{VECTCAT}{position} &
-\cross{VECTCAT}{qelt} \\
-\cross{VECTCAT}{qsetelt!} &
-\cross{VECTCAT}{reduce} &
-\cross{VECTCAT}{remove} &
-\cross{VECTCAT}{removeDuplicates} &
-\cross{VECTCAT}{reverse} \\
-\cross{VECTCAT}{reverse!} &
-\cross{VECTCAT}{sample} &
-\cross{VECTCAT}{select} &
-\cross{VECTCAT}{setelt} &
-\cross{VECTCAT}{size?} \\
-\cross{VECTCAT}{sort} &
-\cross{VECTCAT}{sort!} &
-\cross{VECTCAT}{sorted?} &
-\cross{VECTCAT}{swap!} &
-\cross{VECTCAT}{zero} \\
-\cross{VECTCAT}{\#?} &
-\cross{VECTCAT}{?*?} &
-\cross{VECTCAT}{?+?} &
-\cross{VECTCAT}{?-?} &
-\cross{VECTCAT}{?$<$?} \\
-\cross{VECTCAT}{?$<=$?} &
-\cross{VECTCAT}{?=?} &
-\cross{VECTCAT}{?$>$?} &
-\cross{VECTCAT}{?$>=$?} &
-\cross{VECTCAT}{-?} \\
-\cross{VECTCAT}{?.?} &
-\cross{VECTCAT}{?\~{}=?} &&&
+\cross{VSPACE}{0} &
+\cross{VSPACE}{coerce} &
+\cross{VSPACE}{dimension} &
+\cross{VSPACE}{hash} &
+\cross{VSPACE}{latex} \\
+\cross{VSPACE}{sample} &
+\cross{VSPACE}{subtractIfCan} &
+\cross{VSPACE}{zero?} &
+\cross{VSPACE}{?\~{}=?} &
+\cross{VSPACE}{?*?} \\
+\cross{VSPACE}{?+?} &
+\cross{VSPACE}{?-?} &
+\cross{VSPACE}{-?} &
+\cross{VSPACE}{?/?} &
+\cross{VSPACE}{?=?} \\
 \end{tabular}
 
-{\bf Attributes Exported:}
+{\bf Attributes exported:}
 \begin{itemize}
-\item {\bf \cross{VECTCAT}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf \cross{VECTCAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{VSPACE}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{VSPACE}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
 \end{itemize}
 
+These are directly exported but not implemented:
+\begin{verbatim}
+ dimension : () -> CardinalNumber
+\end{verbatim}
+
 These are implemented by this category:
 \begin{verbatim}
- cross : (%,%) -> % if R has RING
- dot : (%,%) -> R if R has RING
- length : % -> R if R has RING and R has RADCAT
- magnitude : % -> R if R has RING and R has RADCAT
- outerProduct : (%,%) -> Matrix R if R has RING
- zero : NonNegativeInteger -> % if R has ABELMON
- ?*? : (Integer,%) -> % if R has ABELGRP
- ?*? : (%,R) -> % if R has MONOID
- ?*? : (R,%) -> % if R has MONOID
- ?-? : (%,%) -> % if R has ABELGRP
- -? : % -> % if R has ABELGRP         
- ?+? : (%,%) -> % if R has ABELSG
+ ?/? : (%,S) -> %
 \end{verbatim}
 
-These exports come from \refto{OneDimensionalArrayAggregate}(R:Type):
+These exports come from \refto{Module}():
 \begin{verbatim}
- any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- coerce : % -> OutputForm if R has SETCAT
- concat : (R,%) -> %
- concat : (%,R) -> %                  
- concat : List % -> %
- concat : (%,%) -> %                  
- construct : List R -> %
- convert : % -> InputForm if R has KONVERT INFORM
- copy : % -> %                        
- copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
- count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
- delete : (%,Integer) -> %
- delete : (%,UniversalSegment Integer) -> %
- elt : (%,Integer,R) -> R
- empty : () -> %                      
- empty? : % -> Boolean
- entries : % -> List R                
- entry? : (R,%) -> Boolean if $ has finiteAggregate and R has SETCAT
- eq? : (%,%) -> Boolean
- eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
- every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- fill! : (%,R) -> % if $ has shallowlyMutable
- find : ((R -> Boolean),%) -> Union(R,"failed")
- first : % -> R if Integer has ORDSET
- hash : % -> SingleInteger if R has SETCAT
- index? : (Integer,%) -> Boolean      
- indices : % -> List Integer
- insert : (%,%,Integer) -> %          
- insert : (R,%,Integer) -> %
- latex : % -> String if R has SETCAT
- less? : (%,NonNegativeInteger) -> Boolean
- map : ((R -> R),%) -> %
- map : (((R,R) -> R),%,%) -> %        
- map! : ((R -> R),%) -> % if $ has shallowlyMutable
- max : (%,%) -> % if R has ORDSET
- maxIndex : % -> Integer if Integer has ORDSET
- member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
- members : % -> List R if $ has finiteAggregate
- merge : (%,%) -> % if R has ORDSET
- merge : (((R,R) -> Boolean),%,%) -> %
- min : (%,%) -> % if R has ORDSET
- minIndex : % -> Integer if Integer has ORDSET
- more? : (%,NonNegativeInteger) -> Boolean
- new : (NonNegativeInteger,R) -> %    
- parts : % -> List R if $ has finiteAggregate
- position : (R,%) -> Integer if R has SETCAT
- position : ((R -> Boolean),%) -> Integer
- position : (R,%,Integer) -> Integer if R has SETCAT
- qelt : (%,Integer) -> R
- qsetelt! : (%,Integer,R) -> R if $ has shallowlyMutable
- reduce : (((R,R) -> R),%) -> R if $ has finiteAggregate
- reduce : (((R,R) -> R),%,R) -> R if $ has finiteAggregate
- reduce : (((R,R) -> R),%,R,R) -> R if R has SETCAT and $ has finiteAggregate
- remove : ((R -> Boolean),%) -> % if $ has finiteAggregate
- remove : (R,%) -> % if R has SETCAT and $ has finiteAggregate
- removeDuplicates : % -> % if R has SETCAT and $ has finiteAggregate
- reverse : % -> %                     
- reverse! : % -> % if $ has shallowlyMutable
- sample : () -> %
- select : ((R -> Boolean),%) -> % if $ has finiteAggregate
- setelt : (%,Integer,R) -> R if $ has shallowlyMutable
- setelt : (%,UniversalSegment Integer,R) -> R if $ has shallowlyMutable
- size? : (%,NonNegativeInteger) -> Boolean
- sort : % -> % if R has ORDSET
- sort : (((R,R) -> Boolean),%) -> %
- sort! : % -> % if R has ORDSET and $ has shallowlyMutable
- sort! : (((R,R) -> Boolean),%) -> % if $ has shallowlyMutable
- sorted? : % -> Boolean if R has ORDSET
- sorted? : (((R,R) -> Boolean),%) -> Boolean
- swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?.? : (%,Integer) -> R               
- ?.? : (%,UniversalSegment Integer) -> %
- ?=? : (%,%) -> Boolean if R has SETCAT
- ?<? : (%,%) -> Boolean if R has ORDSET
- ?<=? : (%,%) -> Boolean if R has ORDSET
- ?>? : (%,%) -> Boolean if R has ORDSET
- ?>=? : (%,%) -> Boolean if R has ORDSET
- ?~=? : (%,%) -> Boolean if R has SETCAT
+ ?*? : (%,S) -> %                     
+ 0 : () -> %
+ coerce : % -> OutputForm             
+ hash : % -> SingleInteger            
+ latex : % -> String
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (S,%) -> %
+ ?*? : (Integer,%) -> %               
+ ?*? : (PositiveInteger,%) -> %
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?=? : (%,%) -> Boolean               
 \end{verbatim}
 
-<<category VECTCAT VectorCategory>>=
-)abbrev category VECTCAT VectorCategory
+<<category VSPACE VectorSpace>>=
+)abbrev category VSPACE VectorSpace
 ++ Author:
 ++ Date Created:
 ++ Date Last Updated:
 ++ Basic Functions:
-++ Related Constructors: DirectProductCategory, Vector, IndexedVector
+++ Related Constructors:
 ++ Also See:
 ++ AMS Classifications:
 ++ Keywords:
 ++ References:
 ++ Description:
-++ \spadtype{VectorCategory} represents the type of vector like objects,
-++ i.e. finite sequences indexed by some finite segment of the
-++ integers. The operations available on vectors depend on the structure
-++ of the underlying components. Many operations from the component domain
-++ are defined for vectors componentwise. It can by assumed that extraction or
-++ updating components can be done in constant time.
- 
-VectorCategory(R:Type): Category == OneDimensionalArrayAggregate R with
-    if R has AbelianSemiGroup then
-      _+ : (%, %) -> %
-        ++ x + y returns the component-wise sum of the vectors x and y.
-        ++ Error: if x and y are not of the same length.
-    if R has AbelianMonoid then
-      zero: NonNegativeInteger -> %
-        ++ zero(n) creates a zero vector of length n.
-    if R has AbelianGroup then
-      _- : % -> %
-        ++ -x negates all components of the vector x.
-      _- : (%, %) -> %
-        ++ x - y returns the component-wise difference of the vectors x and y.
-        ++ Error: if x and y are not of the same length.
-      _* : (Integer, %) -> %
-        ++ n * y multiplies each component of the vector y by the integer n.
-    if R has Monoid then
-      _* : (R, %) -> %
-        ++ r * y multiplies the element r times each component of the vector y.
-      _* : (%, R) -> %
-        ++ y * r multiplies each component of the vector y by the element r.
-    if R has Ring then
-      dot: (%, %) -> R
-        ++ dot(x,y) computes the inner product of the two vectors x and y.
-        ++ Error: if x and y are not of the same length.
-      outerProduct: (%, %) -> Matrix R
-        ++ outerProduct(u,v) constructs the matrix whose (i,j)'th element is
-        ++ u(i)*v(j).
-      cross: (%, %) -> %
-        ++ vectorProduct(u,v) constructs the cross product of u and v.
-        ++ Error: if u and v are not of length 3.
-    if R has RadicalCategory and R has Ring then
-      length: % -> R
-        ++ length(v) computes the sqrt(dot(v,v)), i.e. the magnitude
-      magnitude: % -> R
-        ++ magnitude(v) computes the sqrt(dot(v,v)), i.e. the length
- add
-    if R has AbelianSemiGroup then
-      u + v ==
-        (n := #u) ^= #v => error "Vectors must be of the same length"
-        map(_+ , u, v)
- 
-    if R has AbelianMonoid then
-      zero n == new(n, 0)
- 
-    if R has AbelianGroup then
-      - u             == map(- #1, u)
-
-      n:Integer * u:% == map(n * #1, u)
-
-      u - v           == u + (-v)
- 
-    if R has Monoid then
-      u:% * r:R       == map(#1 * r, u)
-
-      r:R * u:%       == map(r * #1, u)
- 
-    if R has Ring then
-      dot(u, v) ==
-        #u ^= #v => error "Vectors must be of the same length"
-        _+/[qelt(u, i) * qelt(v, i) for i in minIndex u .. maxIndex u]
-
-      outerProduct(u, v) ==
-        matrix [[qelt(u, i) * qelt(v,j) for i in minIndex u .. maxIndex u] _
-                for j in minIndex v .. maxIndex v]
-
-      cross(u, v) ==
-        #u ^= 3 or #v ^= 3 => error "Vectors must be of length 3"
-        construct [qelt(u, 2)*qelt(v, 3) - qelt(u, 3)*qelt(v, 2) , _
-                   qelt(u, 3)*qelt(v, 1) - qelt(u, 1)*qelt(v, 3) , _
-                   qelt(u, 1)*qelt(v, 2) - qelt(u, 2)*qelt(v, 1) ]
+++ Vector Spaces (not necessarily finite dimensional) over a field.
 
-    if R has RadicalCategory and R has Ring then
-      length p ==
-         sqrt(dot(p,p))
+VectorSpace(S:Field): Category ==  Module(S) with
+    "/"      : (%, S) -> %
+      ++ x/y divides the vector x by the scalar y.
+    dimension: () -> CardinalNumber
+      ++ dimension() returns the dimensionality of the vector space.
+  add
+    (v:% / s:S):% == inv(s) * v
 
-      magnitude p ==
-         sqrt(dot(p,p))
- 
 @
-<<VECTCAT.dotabb>>=
-"VECTCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=VECTCAT"];
-"VECTCAT" -> "A1AGG"
+<<VSPACE.dotabb>>=
+"VSPACE"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=VSPACE"];
+"VSPACE" -> "MODULE"
 
 @
-<<VECTCAT.dotfull>>=
-"VectorCategory(a:Type)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=VECTCAT"];
-"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
-
-"VectorCategory(a:Ring)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=VECTCAT"];
-"VectorCategory(a:Ring)" -> "VectorCategory(a:Type)"
+<<VSPACE.dotfull>>=
+"VectorSpace(a:Field)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=VSPACE"];
+"VectorSpace(a:Field)" -> "Module(Field)"
 
 @
-<<VECTCAT.dotpic>>=
+<<VSPACE.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"VectorCategory(a:Type)" [color=lightblue];
-"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
+"VectorSpace(a:Field)" [color=lightblue];
+"VectorSpace(a:Field)" -> "Module(Field)"
 
-"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
-"OneDimensionalArrayAggregate(a:Type)" -> 
-    "FiniteLinearAggregate(a:Type)"
+"Module(Field)" [color=seagreen];
+"Module(Field)" -> "Module(a:CommutativeRing)"
 
-"FiniteLinearAggregate(a:Type)" [color=lightblue];
-"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
 
-"LinearAggregate(a:Type)" [color=lightblue];
-"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
-"LinearAggregate(a:Type)" -> "CLAGG..."
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
 
-"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
-"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
 
-"CLAGG..." [color=lightblue];
-"IXAGG..." [color=lightblue];
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"ABELGRP..." [color=lightblue];
 }
 
 @
@@ -30537,2368 +32130,486 @@ digraph pic {
 @
 \chapter{Category Layer 11}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{Algebra}{ALGEBRA}
-\pagepic{ps/v102algebra.ps}{ALGEBRA}{0.65}
+\pagehead{DirectProductCategory}{DIRPCAT}
+\pagepic{ps/v102directproductcategory.ps}{DIRPCAT}{0.40}
 
 {\bf See:}\\
-\pageto{DivisionRing}{DIVRING}
-\pageto{FiniteRankAlgebra}{FINRALG}
-\pageto{FunctionSpace}{FS}
-\pageto{IntegralDomain}{INTDOM}
-\pageto{MonogenicLinearOperator}{MLO}
-\pageto{OctonionCategory}{OC}
-\pageto{QuotientFieldCategory}{QFCAT}
-\pagefrom{Module}{MODULE}
-\pagefrom{Ring}{RING}
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{CoercibleTo}{KOERCE}
+\pagefrom{DifferentialExtension}{DIFEXT}
+\pagefrom{IndexedAggregate}{IXAGG}
+\pagefrom{Finite}{FINITE}
+\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{OrderedRing}{ORDRING}
+\pagefrom{OrderedAbelianMonoidSup}{OAMONS}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
-\cross{ALGEBRA}{1} &
-\cross{ALGEBRA}{0} &
-\cross{ALGEBRA}{characteristic} &
-\cross{ALGEBRA}{coerce} &
-\cross{ALGEBRA}{hash} \\
-\cross{ALGEBRA}{latex} &
-\cross{ALGEBRA}{one?} &
-\cross{ALGEBRA}{recip} &
-\cross{ALGEBRA}{sample} &
-\cross{ALGEBRA}{subtractIfCan} \\
-\cross{ALGEBRA}{zero?} &
-\cross{ALGEBRA}{?*?} &
-\cross{ALGEBRA}{?+?} &
-\cross{ALGEBRA}{?-?} &
-\cross{ALGEBRA}{-?} \\
-\cross{ALGEBRA}{?=?} &
-\cross{ALGEBRA}{?\~{}=?} &
-\cross{ALGEBRA}{?*?} &
-\cross{ALGEBRA}{?**?} &
-\cross{ALGEBRA}{?\^{}?} \\
+\cross{DIRPCAT}{0} &
+\cross{DIRPCAT}{1} &
+\cross{DIRPCAT}{abs} &
+\cross{DIRPCAT}{any?} &
+\cross{DIRPCAT}{characteristic} \\
+\cross{DIRPCAT}{coerce} &
+\cross{DIRPCAT}{copy} &
+\cross{DIRPCAT}{count} &
+\cross{DIRPCAT}{count} &
+\cross{DIRPCAT}{D} \\
+\cross{DIRPCAT}{differentiate} &
+\cross{DIRPCAT}{dimension} &
+\cross{DIRPCAT}{directProduct} &
+\cross{DIRPCAT}{dot} &
+\cross{DIRPCAT}{elt} \\
+\cross{DIRPCAT}{empty} &
+\cross{DIRPCAT}{empty?} &
+\cross{DIRPCAT}{entry?} &
+\cross{DIRPCAT}{entries} &
+\cross{DIRPCAT}{eq?} \\
+\cross{DIRPCAT}{eval} &
+\cross{DIRPCAT}{every?} &
+\cross{DIRPCAT}{fill!} &
+\cross{DIRPCAT}{first} &
+\cross{DIRPCAT}{hash} \\
+\cross{DIRPCAT}{index} &
+\cross{DIRPCAT}{index?} &
+\cross{DIRPCAT}{indices} &
+\cross{DIRPCAT}{latex} &
+\cross{DIRPCAT}{less?} \\
+\cross{DIRPCAT}{lookup} &
+\cross{DIRPCAT}{map} &
+\cross{DIRPCAT}{map!} &
+\cross{DIRPCAT}{max} &
+\cross{DIRPCAT}{maxIndex} \\
+\cross{DIRPCAT}{member?} &
+\cross{DIRPCAT}{members} &
+\cross{DIRPCAT}{min} &
+\cross{DIRPCAT}{minIndex} &
+\cross{DIRPCAT}{more?} \\
+\cross{DIRPCAT}{negative?} &
+\cross{DIRPCAT}{one?} &
+\cross{DIRPCAT}{parts} &
+\cross{DIRPCAT}{positive?} &
+\cross{DIRPCAT}{qelt} \\
+\cross{DIRPCAT}{qsetelt!} &
+\cross{DIRPCAT}{random} &
+\cross{DIRPCAT}{recip} &
+\cross{DIRPCAT}{reducedSystem} &
+\cross{DIRPCAT}{retract} \\
+\cross{DIRPCAT}{retractIfCan} &
+\cross{DIRPCAT}{sample} &
+\cross{DIRPCAT}{setelt} &
+\cross{DIRPCAT}{sign} &
+\cross{DIRPCAT}{size} \\
+\cross{DIRPCAT}{size?} &
+\cross{DIRPCAT}{subtractIfCan} &
+\cross{DIRPCAT}{sup} &
+\cross{DIRPCAT}{swap!} &
+\cross{DIRPCAT}{unitVector} \\
+\cross{DIRPCAT}{zero?} &
+\cross{DIRPCAT}{?\~{}=?} &
+\cross{DIRPCAT}{-?} &
+\cross{DIRPCAT}{?.?} &
+\cross{DIRPCAT}{\#?} \\
+\cross{DIRPCAT}{?*?} &
+\cross{DIRPCAT}{?**?} &
+\cross{DIRPCAT}{?+?} &
+\cross{DIRPCAT}{?-?} &
+\cross{DIRPCAT}{?/?} \\
+\cross{DIRPCAT}{?$<$?} &
+\cross{DIRPCAT}{?$<=$?} &
+\cross{DIRPCAT}{?=?} &
+\cross{DIRPCAT}{?$>$?} &
+\cross{DIRPCAT}{?$>=$?} \\
+\cross{DIRPCAT}{?\^{}?} &&&&
 \end{tabular}
 
-{\bf Attributes exported:}
+{\bf Attributes Exported:}
 \begin{itemize}
-\item {\bf \cross{ALGEBRA}{unitsKnown}}
+\item {\bf \cross{DIRPCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item if \#2 has commutativeRing then commutative(``*'') where
+{\bf \cross{DIRPCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\item if \#2 has unitsKnown then unitsKnown where
+{\bf \cross{DIRPCAT}{unitsKnown}}
 is true if a monoid (a multiplicative semigroup with a 1) has 
 unitsKnown means that  the operation {\tt recip} can only return 
 ``failed'' if its argument is not a unit.
-\item {\bf \cross{ALGEBRA}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{ALGEBRA}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are implemented by this category:
-\begin{verbatim}
- coerce : R -> %
-\end{verbatim}
-
-These exports come from \refto{Ring}():
-\begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- characteristic : () -> NonNegativeInteger
- coerce : Integer -> %                
- coerce : % -> OutputForm
- hash : % -> SingleInteger            
- latex : % -> String
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")
- sample : () -> %                     
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean              
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (Integer,%) -> %
- ?*? : (%,%) -> %                     
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?**? : (%,PositiveInteger) -> %
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
-\end{verbatim}
-
-These exports come from \refto{Module}(R:CommutativeRing):
-\begin{verbatim}
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
-\end{verbatim}
-
-<<category ALGEBRA Algebra>>=
-)abbrev category ALGEBRA Algebra
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ The category of associative algebras (modules which are themselves rings).
-++
-++ Axioms:
-++   \spad{(b+c)::% = (b::%) + (c::%)}
-++   \spad{(b*c)::% = (b::%) * (c::%)}
-++   \spad{(1::R)::% = 1::%}
-++   \spad{b*x = (b::%)*x}
-++   \spad{r*(a*b) = (r*a)*b = a*(r*b)}
-Algebra(R:CommutativeRing): Category ==
-  Join(Ring, Module R) with
-      coerce: R -> %
-          ++ coerce(r) maps the ring element r to a member of the algebra.
- add
-  coerce(x:R):% == x * 1$%
-
-@
-<<ALGEBRA.dotabb>>=
-"ALGEBRA"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"ALGEBRA" -> "RING"
-"ALGEBRA" -> "MODULE"
-
-@
-<<ALGEBRA.dotfull>>=
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "Ring()"
-"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-"Algebra(a:Field)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:Field)" -> "Algebra(a:CommutativeRing)"
-
-"Algebra(a:CommutativeRing)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
-
-"Algebra(IntegralDomain)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(IntegralDomain)" -> "Algebra(a:CommutativeRing)"
-
-@
-<<ALGEBRA.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"Algebra(a:CommutativeRing)" [color=lightblue];
-"Algebra(a:CommutativeRing)" -> "Ring()"
-"Algebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-"Ring()" [color=lightblue];
-"Ring()" -> "Rng()"
-"Ring()" -> "Monoid()"
-"Ring()" -> "LeftModule(a:Ring)"
-
-"Rng()" [color=lightblue];
-"Rng()" -> "ABELGRP..."
-"Rng()" -> "SemiGroup()"
-
-"SemiGroup()" [color=lightblue];
-"SemiGroup()" -> "SETCAT..."
-"SemiGroup()" -> "REPSQ..."
-
-"Monoid()" [color=lightblue];
-"Monoid()" -> "SemiGroup()"
-
-"Module(a:CommutativeRing)" [color=lightblue];
-"Module(a:CommutativeRing)" ->
-  "BiModule(a:CommutativeRing,b:CommutativeRing)"
-
-"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
-"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"ABELGRP..." [color=lightblue];
-"REPSQ..." [color="#00EE00"];
-"SETCAT..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{LieAlgebra}{LIECAT}
-\pagepic{ps/v102liealgebra.ps}{LIECAT}{1.00}
-
-{\bf See:}\\
-\pageto{FreeLieAlgebra}{FLALG}
-\pagefrom{Module}{MODULE}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{LIECAT}{0} &
-\cross{LIECAT}{coerce} &
-\cross{LIECAT}{construct} &
-\cross{LIECAT}{hash} &
-\cross{LIECAT}{latex} \\
-\cross{LIECAT}{sample} &
-\cross{LIECAT}{subtractIfCan} &
-\cross{LIECAT}{zero?} &
-\cross{LIECAT}{?\~{}=?} &
-\cross{LIECAT}{?/?} \\
-\cross{LIECAT}{?*?} &
-\cross{LIECAT}{?+?} &
-\cross{LIECAT}{?-?} &
-\cross{LIECAT}{-?} &
-\cross{LIECAT}{?=?} \\
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{LIECAT}{NullSquare}}
-means that $[x,x] = 0$ holds. See {\tt LieAlgebra}.
-\item {\bf \cross{LIECAT}{JacobiIdentity}}
-means that $[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0$ holds.
-See {\tt LieAlgebra}.
-\item {\bf \cross{LIECAT}{leftUnitary}}
+\item if \#2 has Ring then rightUnitary where
+{\bf \cross{DIRPCAT}{leftUnitary}}
 is true if $1 * x = x$ for all x.
-\item {\bf \cross{LIECAT}{rightUnitary}}
+\item if \#2 has Ring then rightUnitary where
+{\bf \cross{DIRPCAT}{rightUnitary}}
 is true if $x * 1 = x$ for all x.
+\item {\bf nil}
 \end{itemize}
 
 These are directly exported but not implemented:
 \begin{verbatim}
- construct : (%,%) -> %               
+ directProduct : Vector R -> %
+ dot : (%,%) -> R if R has RING
+ unitVector : PositiveInteger -> % if R has RING
+ ?*? : (R,%) -> % if R has MONOID
+ ?*? : (%,R) -> % if R has MONOID
 \end{verbatim}
 
 These are implemented by this category:
 \begin{verbatim}
+ characteristic : () -> NonNegativeInteger if R has RING
+ coerce : Integer -> % 
+   if and(has(R,RetractableTo Integer),
+          has(R,SetCategory)) 
+   or R has RING
+ differentiate : (%,(R -> R)) -> % if R has RING
+ dimension : () -> CardinalNumber if R has FIELD
+ reducedSystem : Matrix % -> Matrix R if R has RING
+ reducedSystem :
+    (Matrix %,Vector %) ->
+       Record(mat: Matrix R,vec: Vector R) 
+          if R has RING
+ size : () -> NonNegativeInteger if R has FINITE
  ?/? : (%,R) -> % if R has FIELD
 \end{verbatim}
 
-These exports come from \refto{Module}(R:Ring):
-\begin{verbatim}
- 0 : () -> %                          
- coerce : % -> OutputForm
- hash : % -> SingleInteger
- latex : % -> String                  
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean                 
- ?~=? : (%,%) -> Boolean
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (%,R) -> %                     
- ?*? : (R,%) -> %
- ?*? : (Integer,%) -> %               
- ?*? : (PositiveInteger,%) -> %
- ?+? : (%,%) -> %                     
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?=? : (%,%) -> Boolean
-\end{verbatim}
-
-<<category LIECAT LieAlgebra>>=
-)abbrev category LIECAT LieAlgebra
-++ Author: Michel Petitot (petitot@lifl.fr).
-++ Date Created: 91
-++ Date Last Updated: 7 Juillet 92
-++ Fix History: compilation v 2.1 le 13 dec 98
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ The category of Lie Algebras.
-++ It is used by the following domains of non-commutative algebra:
-++ \axiomType{LiePolynomial} and 
-++ \axiomType{XPBWPolynomial}. \newline 
-++ Author : Michel Petitot (petitot@lifl.fr).
-LieAlgebra(R: CommutativeRing): Category ==  Module(R) with
-    NullSquare 
-      ++ \axiom{NullSquare} means that \axiom{[x,x] = 0} holds.
-    JacobiIdentity 
-      ++ \axiom{JacobiIdentity} means that 
-      ++ \axiom{[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0} holds.
-    construct:  ($,$) -> $
-      ++ \axiom{construct(x,y)} returns the Lie bracket of \axiom{x} 
-      ++ and \axiom{y}.
-    if R has Field then 
-       "/"   :  ($,R) -> $
-         ++ \axiom{x/r} returns the division of \axiom{x} by \axiom{r}.
-  add
-    if R has Field then x / r == inv(r)$R * x
-
-@
-<<LIECAT.dotabb>>=
-"LIECAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=LIECAT"];
-"LIECAT" -> "MODULE"
-
-@
-<<LIECAT.dotfull>>=
-"LieAlgebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=LIECAT"];
-"LieAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-@
-<<LIECAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"LieAlgebra(a:CommutativeRing)" [color=lightblue];
-"LieAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-"Module(a:CommutativeRing)" [color=lightblue];
-"Module(a:CommutativeRing)" ->
-  "BiModule(a:CommutativeRing,b:CommutativeRing)"
-
-"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
-"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"ABELGRP..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{NonAssociativeAlgebra}{NAALG}
-\pagepic{ps/v102nonassociativealgebra.ps}{NAALG}{0.75}
-
-{\bf See:}\\
-\pageto{FiniteRankNonAssociativeAlgebra}{FINAALG}
-\pagefrom{Module}{MODULE}
-\pagefrom{NonAssociativeRng}{NARNG}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{NAALG}{0} &
-\cross{NAALG}{antiCommutator} &
-\cross{NAALG}{associator} &
-\cross{NAALG}{coerce} &
-\cross{NAALG}{commutator} \\
-\cross{NAALG}{hash} &
-\cross{NAALG}{latex} &
-\cross{NAALG}{leftPower} &
-\cross{NAALG}{plenaryPower} &
-\cross{NAALG}{rightPower} \\
-\cross{NAALG}{sample} &
-\cross{NAALG}{subtractIfCan} &
-\cross{NAALG}{zero?} &
-\cross{NAALG}{?\~{}=?} &
-\cross{NAALG}{?*?} \\
-\cross{NAALG}{?**?} &
-\cross{NAALG}{?+?} &
-\cross{NAALG}{?-?} &
-\cross{NAALG}{-?} &
-\cross{NAALG}{?=?} \\
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item {\bf \cross{NAALG}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{NAALG}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are implemented by this category:
-\begin{verbatim}
- plenaryPower : (%,PositiveInteger) -> %
-\end{verbatim}
-
-These exports come from \refto{NonAssociativeRng}():
-\begin{verbatim}
- 0 : () -> %                          
- antiCommutator : (%,%) -> %
- associator : (%,%,%) -> %            
- coerce : % -> OutputForm
- commutator : (%,%) -> %              
- hash : % -> SingleInteger
- latex : % -> String                  
- leftPower : (%,PositiveInteger) -> %
- rightPower : (%,PositiveInteger) -> %
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean                 
- ?~=? : (%,%) -> Boolean
- ?*? : (PositiveInteger,%) -> %       
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?*? : (Integer,%) -> %
- ?*? : (NonNegativeInteger,%) -> %
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?*? : (%,%) -> %                     
- ?**? : (%,PositiveInteger) -> %
-\end{verbatim}
-
-These exports come from \refto{Module}(R:CommutativeRing):
-\begin{verbatim}
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
-\end{verbatim}
-
-<<category NAALG NonAssociativeAlgebra>>=
-)abbrev category NAALG NonAssociativeAlgebra
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: +, -, *, **
-++ Related Constructors: Algebra
-++ Also See:
-++ AMS Classifications:
-++ Keywords: nonassociative algebra
-++ Reference:
-++  R.D. Schafer: An Introduction to Nonassociative Algebras
-++  Academic Press, New York, 1966
-++ Description:
-++   NonAssociativeAlgebra is the category of non associative algebras
-++   (modules which are themselves non associative rngs).
-++   Axioms
-++      r*(a*b) = (r*a)*b = a*(r*b)
-NonAssociativeAlgebra(R:CommutativeRing): Category == _
-  Join(NonAssociativeRng, Module R) with
-    plenaryPower : (%,PositiveInteger) -> %
-      ++ plenaryPower(a,n) is recursively defined to be
-      ++ \spad{plenaryPower(a,n-1)*plenaryPower(a,n-1)} for \spad{n>1}
-      ++ and \spad{a} for \spad{n=1}.
-  add
-    plenaryPower(a,n) ==
---      one? n => a
-      ( n = 1 ) => a
-      n1 : PositiveInteger := (n-1)::NonNegativeInteger::PositiveInteger
-      plenaryPower(a,n1) * plenaryPower(a,n1)
-
-@
-<<NAALG.dotabb>>=
-"NAALG"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
-"NAALG" -> "NARNG"
-"NAALG" -> "MODULE"
-
-@
-<<NAALG.dotfull>>=
-"NonAssociativeAlgebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
-"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
-"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-@
-<<NAALG.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"NonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
-"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
-"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
-
-"NonAssociativeRng()" [color=lightblue];
-"NonAssociativeRng()" -> "ABELGRP..."
-"NonAssociativeRng()" -> "Monad()"
-
-"Monad()" [color=lightblue];
-"Monad()" -> "SETCAT..."
-"Monad()" -> "REPSQ..."
-
-"Module(a:CommutativeRing)" [color=lightblue];
-"Module(a:CommutativeRing)" ->
-  "BiModule(a:CommutativeRing,b:CommutativeRing)"
-
-"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
-"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"REPSQ..." [color="#00EE00"];
-"SETCAT..." [color=lightblue];
-"ABELGRP..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{PointCategory}{PTCAT}
-\pagepic{ps/v102pointcategory.ps}{PTCAT}{1.00}
-
-{\bf See:}\\
-\pagefrom{VectorCategory}{VECTCAT}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{PTCAT}{any?} &
-\cross{PTCAT}{coerce} &
-\cross{PTCAT}{concat} &
-\cross{PTCAT}{construct} &
-\cross{PTCAT}{convert} \\
-\cross{PTCAT}{copy} &
-\cross{PTCAT}{copyInto!} &
-\cross{PTCAT}{cross} &
-\cross{PTCAT}{count} &
-\cross{PTCAT}{delete} \\
-\cross{PTCAT}{dimension} &
-\cross{PTCAT}{dot} &
-\cross{PTCAT}{elt} &
-\cross{PTCAT}{empty} &
-\cross{PTCAT}{empty?} \\
-\cross{PTCAT}{entry?} &
-\cross{PTCAT}{entries} &
-\cross{PTCAT}{eq?} &
-\cross{PTCAT}{eval} &
-\cross{PTCAT}{every?} \\
-\cross{PTCAT}{extend} &
-\cross{PTCAT}{fill!} &
-\cross{PTCAT}{find} &
-\cross{PTCAT}{first} &
-\cross{PTCAT}{hash} \\
-\cross{PTCAT}{index?} &
-\cross{PTCAT}{indices} &
-\cross{PTCAT}{insert} &
-\cross{PTCAT}{latex} &
-\cross{PTCAT}{length} \\
-\cross{PTCAT}{less?} &
-\cross{PTCAT}{magnitude} &
-\cross{PTCAT}{map} &
-\cross{PTCAT}{map!} &
-\cross{PTCAT}{max} \\
-\cross{PTCAT}{maxIndex} &
-\cross{PTCAT}{member?} &
-\cross{PTCAT}{members} &
-\cross{PTCAT}{merge} &
-\cross{PTCAT}{min} \\
-\cross{PTCAT}{minIndex} &
-\cross{PTCAT}{more?} &
-\cross{PTCAT}{new} &
-\cross{PTCAT}{outerProduct} &
-\cross{PTCAT}{parts} \\
-\cross{PTCAT}{point} &
-\cross{PTCAT}{position} &
-\cross{PTCAT}{qelt} &
-\cross{PTCAT}{qsetelt!} &
-\cross{PTCAT}{reduce} \\
-\cross{PTCAT}{remove} &
-\cross{PTCAT}{removeDuplicates} &
-\cross{PTCAT}{reverse} &
-\cross{PTCAT}{reverse!} &
-\cross{PTCAT}{sample} \\
-\cross{PTCAT}{select} &
-\cross{PTCAT}{setelt} &
-\cross{PTCAT}{size?} &
-\cross{PTCAT}{sort} &
-\cross{PTCAT}{sort!} \\
-\cross{PTCAT}{sorted?} &
-\cross{PTCAT}{swap!} &
-\cross{PTCAT}{zero} &
-\cross{PTCAT}{\#?} &
-\cross{PTCAT}{?.?} \\
-\cross{PTCAT}{?\~{}=?} &
-\cross{PTCAT}{-?} &
-\cross{PTCAT}{?*?} &
-\cross{PTCAT}{?+?} &
-\cross{PTCAT}{?-?} \\
-\cross{PTCAT}{?$<$?} &
-\cross{PTCAT}{?$<=$?} &
-\cross{PTCAT}{?=?} &
-\cross{PTCAT}{?$>$?} &
-\cross{PTCAT}{?$>=$?} \\
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{PTCAT}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf \cross{PTCAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf nil}
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- convert : List R -> %                
- cross : (%,%) -> %                   
- dimension : % -> PositiveInteger     
- extend : (%,List R) -> %
- point : List R -> %
-\end{verbatim}
-
-These exports come from \refto{VectorCategory}(R:Ring):
+These exports come from \refto{IndexedAggregate}(a:SetCategory,R:Type):
 \begin{verbatim}
  any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
  coerce : % -> OutputForm if R has SETCAT
- concat : List % -> %
- concat : (%,%) -> %                  
- concat : (R,%) -> %
- concat : (%,R) -> %                  
- construct : List R -> %
- convert : % -> InputForm if R has KONVERT INFORM
- copy : % -> %
- copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
- count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
- count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- delete : (%,Integer) -> %
- delete : (%,UniversalSegment Integer) -> %
- dot : (%,%) -> R if R has RING
- elt : (%,Integer,R) -> R             
- empty : () -> %
- empty? : % -> Boolean                
- entry? : (R,%) -> Boolean if $ has finiteAggregate and R has SETCAT
- entries : % -> List R
- eq? : (%,%) -> Boolean               
- eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
- every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ copy : % -> %                        
+ count : (R,%) -> NonNegativeInteger 
+   if R has SETCAT 
+   and $ has finiteAggregate
+ count : ((R -> Boolean),%) -> NonNegativeInteger 
+   if $ has finiteAggregate
+ elt : (%,Integer,R) -> R
+ empty : () -> %                      
+ empty? : % -> Boolean
+ entries : % -> List R                
+ entry? : (R,%) -> Boolean 
+   if $ has finiteAggregate 
+   and R has SETCAT
+ eq? : (%,%) -> Boolean
+ eval : (%,List R,List R) -> % 
+   if R has EVALAB R 
+   and R has SETCAT
+ eval : (%,R,R) -> % 
+   if R has EVALAB R 
+   and R has SETCAT
+ eval : (%,Equation R) -> % 
+   if R has EVALAB R 
+   and R has SETCAT
+ eval : (%,List Equation R) -> % 
+   if R has EVALAB R 
+   and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean 
+   if $ has finiteAggregate
  fill! : (%,R) -> % if $ has shallowlyMutable
- find : ((R -> Boolean),%) -> Union(R,"failed")
  first : % -> R if Integer has ORDSET
  hash : % -> SingleInteger if R has SETCAT
  index? : (Integer,%) -> Boolean      
  indices : % -> List Integer
- insert : (%,%,Integer) -> %          
- insert : (R,%,Integer) -> %
- latex : % -> String if R has SETCAT
- length : % -> R if R has RING and R has RADCAT
  less? : (%,NonNegativeInteger) -> Boolean
- magnitude : % -> R if R has RING and R has RADCAT
- map : (((R,R) -> R),%,%) -> %        
- map : ((R -> R),%) -> %
+ latex : % -> String if R has SETCAT
+ map : ((R -> R),%) -> %              
  map! : ((R -> R),%) -> % if $ has shallowlyMutable
- max : (%,%) -> % if R has ORDSET
  maxIndex : % -> Integer if Integer has ORDSET
- member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ member? : (R,%) -> Boolean 
+   if R has SETCAT 
+   and $ has finiteAggregate
  members : % -> List R if $ has finiteAggregate
- merge : (%,%) -> % if R has ORDSET
- merge : (((R,R) -> Boolean),%,%) -> %
- min : (%,%) -> % if R has ORDSET
  minIndex : % -> Integer if Integer has ORDSET
  more? : (%,NonNegativeInteger) -> Boolean
- new : (NonNegativeInteger,R) -> %    
- outerProduct : (%,%) -> Matrix R if R has RING
  parts : % -> List R if $ has finiteAggregate
- position : (R,%,Integer) -> Integer if R has SETCAT
- position : (R,%) -> Integer if R has SETCAT
- position : ((R -> Boolean),%) -> Integer
- qelt : (%,Integer) -> R              
+ qelt : (%,Integer) -> R
  qsetelt! : (%,Integer,R) -> R if $ has shallowlyMutable
- reduce : (((R,R) -> R),%) -> R if $ has finiteAggregate
- reduce : (((R,R) -> R),%,R) -> R if $ has finiteAggregate
- reduce : (((R,R) -> R),%,R,R) -> R if R has SETCAT and $ has finiteAggregate
- remove : ((R -> Boolean),%) -> % if $ has finiteAggregate
- remove : (R,%) -> % if R has SETCAT and $ has finiteAggregate
- removeDuplicates : % -> % if R has SETCAT and $ has finiteAggregate
- reverse : % -> %
- reverse! : % -> % if $ has shallowlyMutable
  sample : () -> %                     
- select : ((R -> Boolean),%) -> % if $ has finiteAggregate
- setelt : (%,UniversalSegment Integer,R) -> R if $ has shallowlyMutable
  setelt : (%,Integer,R) -> R if $ has shallowlyMutable
  size? : (%,NonNegativeInteger) -> Boolean
- sort : % -> % if R has ORDSET
- sort : (((R,R) -> Boolean),%) -> %
- sort! : % -> % if R has ORDSET and $ has shallowlyMutable
- sort! : (((R,R) -> Boolean),%) -> % if $ has shallowlyMutable
- sorted? : % -> Boolean if R has ORDSET
- sorted? : (((R,R) -> Boolean),%) -> Boolean
  swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
- zero : NonNegativeInteger -> % if R has ABELMON
  #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?.? : (%,Integer) -> R
- ?.? : (%,UniversalSegment Integer) -> %
- ?~=? : (%,%) -> Boolean if R has SETCAT
- ?<? : (%,%) -> Boolean if R has ORDSET
- ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?.? : (%,Integer) -> R               
  ?=? : (%,%) -> Boolean if R has SETCAT
- ?>? : (%,%) -> Boolean if R has ORDSET
- ?>=? : (%,%) -> Boolean if R has ORDSET
- ?*? : (Integer,%) -> % if R has ABELGRP
- ?*? : (%,R) -> % if R has MONOID
- ?*? : (R,%) -> % if R has MONOID
- ?-? : (%,%) -> % if R has ABELGRP
- -? : % -> % if R has ABELGRP         
- ?+? : (%,%) -> % if R has ABELSG
-\end{verbatim}
-
-<<category PTCAT PointCategory>>=
-)abbrev category PTCAT PointCategory
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Operations: point, elt, setelt, copy, dimension, minIndex, maxIndex,
-++ convert
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: 
-++ References:
-++ Description: PointCategory is the category of points in space which
-++ may be plotted via the graphics facilities.  Functions are provided for
-++ defining points and handling elements of points.
- 
-PointCategory(R:Ring) : Category == VectorCategory(R) with
-  point: List R -> %
-    ++ point(l) returns a point category defined by a list l of elements from 
-    ++ the domain R.
-  dimension: % -> PositiveInteger
-    ++ dimension(s) returns the dimension of the point category s.
-  convert: List R -> %
-    ++ convert(l) takes a list of elements, l, from the domain Ring and 
-    ++ returns the form of point category.
-  cross: (%,%) -> %
-      ++ cross(p,q) computes the cross product of the two points \spad{p}
-      ++ and \spad{q}. Error if the p and q are not 3 dimensional
-  extend : (%,List R) -> %
-	++ extend(x,l,r) \undocumented
-
-@
-<<PTCAT.dotabb>>=
-"PTCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=PTCAT"];
-"PTCAT" -> "VECTCAT"
-@
-<<PTCAT.dotfull>>=
-"PointCategory(a:Ring)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=PTCAT"];
-"PointCategory(a:Ring)" -> "VectorCategory(a:Ring)"
-
-@
-<<PTCAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"PointCategory(a:Ring)" [color=lightblue];
-"PointCategory(a:Ring)" -> "VectorCategory(a:Ring)"
-
-"VectorCategory(a:Ring)" [color=seagreen];
-"VectorCategory(a:Ring)" -> "VectorCategory(a:Type)"
-
-"VectorCategory(a:Type)" [color=lightblue];
-"VectorCategory(a:Type)" -> "OneDimensionalArrayAggregate(a:Type)"
-
-"OneDimensionalArrayAggregate(a:Type)" [color=lightblue];
-"OneDimensionalArrayAggregate(a:Type)" -> 
-    "FiniteLinearAggregate(a:Type)"
-
-"FiniteLinearAggregate(a:Type)" [color=lightblue];
-"FiniteLinearAggregate(a:Type)" -> "LinearAggregate(a:Type)"
-
-"LinearAggregate(a:Type)" [color=lightblue];
-"LinearAggregate(a:Type)" -> "IndexedAggregate(b:Integer,a:Type)"
-"LinearAggregate(a:Type)" -> "CLAGG..."
-
-"IndexedAggregate(b:Integer,a:Type)" [color=seagreen];
-"IndexedAggregate(b:Integer,a:Type)" -> "IXAGG..."
-
-"CLAGG..." [color=lightblue];
-"IXAGG..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{SquareMatrixCategory}{SMATCAT}
-\pagepic{ps/v102squarematrixcategory.ps}{SMATCAT}{0.25}
-
-{\bf See:}\\
-\pagefrom{BiModule}{BMODULE}
-\pagefrom{DifferentialExtension}{DIFEXT}
-\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
-\pagefrom{FullyRetractableTo}{FRETRCT}
-\pagefrom{RectangularMatrixCategory}{RMATCAT}
-
-{\bf Exports:}\\
-\begin{tabular}{lll}
-\cross{SMATCAT}{0} &
-\cross{SMATCAT}{1} &
-\cross{SMATCAT}{antisymmetric?} \\
-\cross{SMATCAT}{any?} &
-\cross{SMATCAT}{characteristic} &
-\cross{SMATCAT}{coerce} \\
-\cross{SMATCAT}{column} &
-\cross{SMATCAT}{copy} &
-\cross{SMATCAT}{count} \\
-\cross{SMATCAT}{D} &
-\cross{SMATCAT}{determinant} &
-\cross{SMATCAT}{differentiate} \\
-\cross{SMATCAT}{diagonal} &
-\cross{SMATCAT}{diagonal?} &
-\cross{SMATCAT}{diagonalMatrix} \\
-\cross{SMATCAT}{diagonalProduct} &
-\cross{SMATCAT}{elt} &
-\cross{SMATCAT}{empty} \\
-\cross{SMATCAT}{empty?} &
-\cross{SMATCAT}{eq?} &
-\cross{SMATCAT}{eval} \\
-\cross{SMATCAT}{every?} &
-\cross{SMATCAT}{exquo} &
-\cross{SMATCAT}{hash} \\
-\cross{SMATCAT}{inverse} &
-\cross{SMATCAT}{latex} &
-\cross{SMATCAT}{less?} \\
-\cross{SMATCAT}{listOfLists} &
-\cross{SMATCAT}{map} &
-\cross{SMATCAT}{map!} \\
-\cross{SMATCAT}{matrix} &
-\cross{SMATCAT}{maxColIndex} &
-\cross{SMATCAT}{maxRowIndex} \\
-\cross{SMATCAT}{member?} &
-\cross{SMATCAT}{members} &
-\cross{SMATCAT}{minColIndex} \\
-\cross{SMATCAT}{minordet} &
-\cross{SMATCAT}{minRowIndex} &
-\cross{SMATCAT}{more?} \\
-\cross{SMATCAT}{ncols} &
-\cross{SMATCAT}{nrows} &
-\cross{SMATCAT}{nullSpace} \\
-\cross{SMATCAT}{nullity} &
-\cross{SMATCAT}{one?} &
-\cross{SMATCAT}{parts} \\
-\cross{SMATCAT}{qelt} &
-\cross{SMATCAT}{rank} &
-\cross{SMATCAT}{recip} \\
-\cross{SMATCAT}{reducedSystem} &
-\cross{SMATCAT}{retract} &
-\cross{SMATCAT}{retractIfCan} \\
-\cross{SMATCAT}{row} &
-\cross{SMATCAT}{rowEchelon} &
-\cross{SMATCAT}{sample} \\
-\cross{SMATCAT}{scalarMatrix} &
-\cross{SMATCAT}{size?} &
-\cross{SMATCAT}{square?} \\
-\cross{SMATCAT}{subtractIfCan} &
-\cross{SMATCAT}{symmetric?} &
-\cross{SMATCAT}{trace} \\
-\cross{SMATCAT}{zero?} &
-\cross{SMATCAT}{\#?} &
-\cross{SMATCAT}{?\^{}?} \\
-\cross{SMATCAT}{?*?} &
-\cross{SMATCAT}{?**?} &
-\cross{SMATCAT}{?+?} \\
-\cross{SMATCAT}{?-?} &
-\cross{SMATCAT}{-?} &
-\cross{SMATCAT}{?=?} \\
-\cross{SMATCAT}{?\~{}=?} &
-\cross{SMATCAT}{?/?} &
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{SMATCAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf \cross{SMATCAT}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{SMATCAT}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\item {\bf \cross{SMATCAT}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf nil}
-\end{itemize}
-
-TPDHERE: How did MATCAT get in the type tower?
-\begin{verbatim}
- determinant : % -> R if R has commutative *
- inverse : % -> Union(%,"failed") if R has FIELD
-\end{verbatim}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- diagonalMatrix : List R -> %
- minordet : % -> R if R has commutative *
- scalarMatrix : R -> %                
- ?*? : (Row,%) -> Row                 
- ?*? : (%,Col) -> Col
+ ?~=? : (%,%) -> Boolean if R has SETCAT
 \end{verbatim}
 
-These are implemented by this category:
+These exports come from \refto{CoercibleTo}(Vector(R:Type)):
 \begin{verbatim}
- coerce : R -> %                      
- diagonal : % -> Row
- diagonalProduct : % -> R             
- differentiate : (%,(R -> R)) -> %
- reducedSystem : Matrix % -> Matrix R
- reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix R,vec: Vector R)
- retract : % -> R
- retractIfCan : % -> Union(R,"failed")
- trace : % -> R
- ?**? : (%,Integer) -> % if R has FIELD
- ?**? : (%,NonNegativeInteger) -> %
+ coerce : % -> Vector R
 \end{verbatim}
 
-These exports come from \refto{DifferentialExtension}(R:Ring):
+These exports come from \refto{FullyRetractableTo}(R:SetCategory):
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- characteristic : () -> NonNegativeInteger
- coerce : Integer -> %
- coerce : % -> OutputForm             
- D : % -> % if R has DIFRING          
- D : (%,NonNegativeInteger) -> % if R has DIFRING
- D : (%,(R -> R)) -> %
- D : (%,(R -> R),NonNegativeInteger) -> %
- D : (%,Symbol) -> % if R has PDRING SYMBOL
- D : (%,List Symbol) -> % if R has PDRING SYMBOL
- D : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
- D : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
- differentiate : (%,List Symbol) -> % if R has PDRING SYMBOL
- differentiate : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
- differentiate : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
- differentiate : (%,NonNegativeInteger) -> % if R has DIFRING
- differentiate : % -> % if R has DIFRING
- differentiate : (%,(R -> R),NonNegativeInteger) -> %
- differentiate : (%,Symbol) -> % if R has PDRING SYMBOL
- hash : % -> SingleInteger            
- latex : % -> String
- one? : % -> Boolean                  
- recip : % -> Union(%,"failed")       
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean                 
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
- ?*? : (%,%) -> %                     
- ?*? : (Integer,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (NonNegativeInteger,%) -> %
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
+ coerce : R -> % if R has SETCAT
+ coerce : Fraction Integer -> % 
+   if and(has(R,RetractableTo Fraction Integer),
+          has(R,SetCategory))
+ retract : % -> Integer 
+   if and(has(R,RetractableTo Integer),
+          has(R,SetCategory))
+ retract : % -> R if R has SETCAT
+ retract : % -> Fraction Integer 
+   if and(has(R,RetractableTo Fraction Integer),
+          has(R,SetCategory))
+ retractIfCan : % -> Union(Integer,"failed") 
+   if and(has(R,RetractableTo Integer),
+          has(R,SetCategory))
+ retractIfCan : % -> Union(R,"failed") if R has SETCAT
+ retractIfCan : % -> Union(Fraction Integer,"failed") 
+   if and(has(R,RetractableTo Fraction Integer),
+          has(R,SetCategory))
 \end{verbatim}
 
 These exports come from \refto{BiModule}(R:Ring,R:Ring):
 \begin{verbatim}
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
-\end{verbatim}
-
-These exports come from\\
-\refto{RectangularMatrixCategory}(ndim,ndim,R,Row,Col)\\
-where ndim:NonNegativeInteger, R:Ring, Row:DirectProductCategory(ndim,R)\\
-Col:DirectProductCategory(ndim,R):
-\begin{verbatim}
- antisymmetric? : % -> Boolean
- any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- column : (%,Integer) -> Col
- copy : % -> %                        
- count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
- count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- diagonal? : % -> Boolean             
- elt : (%,Integer,Integer) -> R
- elt : (%,Integer,Integer,R) -> R     
- empty : () -> %
- empty? : % -> Boolean                
- eq? : (%,%) -> Boolean
- eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
- every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- exquo : (%,R) -> Union(%,"failed") if R has INTDOM
- less? : (%,NonNegativeInteger) -> Boolean
- listOfLists : % -> List List R       
- map : ((R -> R),%) -> %
- map : (((R,R) -> R),%,%) -> %        
- map! : ((R -> R),%) -> % if $ has shallowlyMutable
- matrix : List List R -> %
- maxColIndex : % -> Integer           
- maxRowIndex : % -> Integer
- minColIndex : % -> Integer           
- minRowIndex : % -> Integer
- members : % -> List R if $ has finiteAggregate
- member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
- more? : (%,NonNegativeInteger) -> Boolean
- ncols : % -> NonNegativeInteger      
- nrows : % -> NonNegativeInteger
- nullity : % -> NonNegativeInteger if R has INTDOM
- nullSpace : % -> List Col if R has INTDOM
- parts : % -> List R if $ has finiteAggregate
- qelt : (%,Integer,Integer) -> R
- rank : % -> NonNegativeInteger if R has INTDOM
- row : (%,Integer) -> Row             
- rowEchelon : % -> % if R has EUCDOM
- size? : (%,NonNegativeInteger) -> Boolean
- square? : % -> Boolean
- symmetric? : % -> Boolean            
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?/? : (%,R) -> % if R has FIELD
-\end{verbatim}
-
-These exports come from \refto{FullyRetractableTo}(R:Ring):
-\begin{verbatim}
- coerce : Fraction Integer -> % if R has RETRACT FRAC INT
- retract : % -> Fraction Integer if R has RETRACT FRAC INT
- retract : % -> Integer if R has RETRACT INT
- retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
- retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
-\end{verbatim}
-
-These exports come from \refto{FullyLinearlyExplicitRingOver}(R:Ring):
-\begin{verbatim}
- reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix Integer,vec: Vector Integer) if R has LINEXP INT
- reducedSystem : Matrix % -> Matrix Integer if R has LINEXP INT
-\end{verbatim}
-
-<<category SMATCAT SquareMatrixCategory>>=
-)abbrev category SMATCAT SquareMatrixCategory
-++ Authors: Grabmeier, Gschnitzer, Williamson
-++ Date Created: 1987
-++ Date Last Updated: July 1990
-++ Basic Operations:
-++ Related Domains: SquareMatrix(ndim,R)
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ Examples:
-++ References:
-++ Description:
-++   \spadtype{SquareMatrixCategory} is a general square matrix category which
-++   allows different representations and indexing schemes.  Rows and
-++   columns may be extracted with rows returned as objects of
-++   type Row and colums returned as objects of type Col.
-SquareMatrixCategory(ndim,R,Row,Col): Category == Definition where
-  ndim : NonNegativeInteger
-  R    : Ring
-  Row  : DirectProductCategory(ndim,R)
-  Col  : DirectProductCategory(ndim,R)
-  I ==> Integer
-
-  Definition ==> Join(DifferentialExtension R, BiModule(R, R),_
-                      RectangularMatrixCategory(ndim,ndim,R,Row,Col),_
-                      FullyRetractableTo R,_
-                      FullyLinearlyExplicitRingOver R) with
-    if R has CommutativeRing then Module(R)
-    scalarMatrix: R -> %
-      ++ \spad{scalarMatrix(r)} returns an n-by-n matrix with r's on the
-      ++ diagonal and zeroes elsewhere.
-    diagonalMatrix: List R -> %
-      ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
-      ++ of l on the diagonal.
-    diagonal: % -> Row
-      ++ \spad{diagonal(m)} returns a row consisting of the elements on the
-      ++ diagonal of the matrix m.
-    trace: % -> R
-      ++ \spad{trace(m)} returns the trace of the matrix m. this is the sum
-      ++ of the elements on the diagonal of the matrix m.
-    diagonalProduct: % -> R
-      ++ \spad{diagonalProduct(m)} returns the product of the elements on the
-      ++ diagonal of the matrix m.
-    "*": (%,Col) -> Col
-      ++ \spad{x * c} is the product of the matrix x and the column vector c.
-      ++ Error: if the dimensions are incompatible.
-    "*": (Row,%) -> Row
-      ++ \spad{r * x} is the product of the row vector r and the matrix x.
-      ++ Error: if the dimensions are incompatible.
-
---% Linear algebra
-
-    if R has commutative("*") then
-      Algebra R
-      determinant: % -> R
-        ++ \spad{determinant(m)} returns the determinant of the matrix m.
-      minordet: % -> R
-        ++ \spad{minordet(m)} computes the determinant of the matrix m
-        ++ using minors.
-    if R has Field then
-      inverse: % -> Union(%,"failed")
-        ++ \spad{inverse(m)} returns the inverse of the matrix m, if that
-        ++ matrix is invertible and returns "failed" otherwise.
-      "**": (%,Integer) -> %
-        ++ \spad{m**n} computes an integral power of the matrix m.
-        ++ Error: if the matrix is not invertible.
-
-   add
-    minr ==> minRowIndex
-    maxr ==> maxRowIndex
-    minc ==> minColIndex
-    maxc ==> maxColIndex
-    mini ==> minIndex
-    maxi ==> maxIndex
-
-    positivePower:(%,Integer) -> %
-    positivePower(x,n) ==
---      one? n => x
-      (n = 1) => x
-      odd? n => x * positivePower(x,n - 1)
-      y := positivePower(x,n quo 2)
-      y * y
-
-    x:% ** n:NonNegativeInteger ==
-      zero? n => scalarMatrix 1
-      positivePower(x,n)
-
-    coerce(r:R) == scalarMatrix r
-
-    equation2R: Vector % -> Matrix R
-
-    differentiate(x:%,d:R -> R) == map(d,x)
-
-    diagonal x ==
-      v:Vector(R) := new(ndim,0)
-      for i in minr x .. maxr x
-        for j in minc x .. maxc x
-          for k in minIndex v .. maxIndex v repeat
-            qsetelt_!(v, k, qelt(x, i, j))
-      directProduct v
-
-    retract(x:%):R ==
-      diagonal? x => retract diagonal x
-      error "Not retractable"
-
-    retractIfCan(x:%):Union(R, "failed") ==
-      diagonal? x => retractIfCan diagonal x
-      "failed"
-
-    equation2R v ==
-      ans:Matrix(Col) := new(ndim,#v,0)
-      for i in minr ans .. maxr ans repeat
-        for j in minc ans .. maxc ans repeat
-          qsetelt_!(ans, i, j, column(qelt(v, j), i))
-      reducedSystem ans
-
-    reducedSystem(x:Matrix %):Matrix(R) ==
-      empty? x => new(0,0,0)
-      reduce(vertConcat, [equation2R row(x, i)
-                               for i in minr x .. maxr x])$List(Matrix R)
-
-    reducedSystem(m:Matrix %, v:Vector %):
-     Record(mat:Matrix R, vec:Vector R) ==
-      vh:Vector(R) :=
-        empty? v => new(0,0)
-        rh := reducedSystem(v::Matrix %)@Matrix(R)
-        column(rh, minColIndex rh)
-      [reducedSystem(m)@Matrix(R), vh]
-
-    trace x ==
-      tr : R := 0
-      for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
-        tr := tr + x(i,j)
-      tr
-
-    diagonalProduct x ==
-      pr : R := 1
-      for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
-        pr := pr * x(i,j)
-      pr
-
-    if R has Field then
-
-      x:% ** n:Integer ==
-        zero? n => scalarMatrix 1
-        positive? n => positivePower(x,n)
-        (xInv := inverse x) case "failed" =>
-          error "**: matrix must be invertible"
-        positivePower(xInv :: %,-n)
-
-@
-<<SMATCAT.dotabb>>=
-"SMATCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=SMATCAT"];
-"SMATCAT" -> "BMODULE"
-"SMATCAT" -> "DIFEXT"
-"SMATCAT" -> "FLINEXP"
-"SMATCAT" -> "FRETRCT"
-"SMATCAT" -> "RMATCAT"
-
-@
-<<SMATCAT.dotfull>>=
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=SMATCAT"];
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "BiModule(a:Ring,b:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "DifferentialExtension(a:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "FullyLinearlyExplicitRingOver(a:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "FullyRetractableTo(a:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
-
-@
-<<SMATCAT.dotpic>>=
-<<RMATCAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- [color=lightblue];
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "BiModule(a:Ring,b:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "DifferentialExtension(a:Ring)"
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "FLINEXP..."
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "FRETRCT..."
-"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
- -> "RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
-
-"DifferentialExtension(a:Ring)" [color=lightblue];
-"DifferentialExtension(a:Ring)" -> "Ring()"
-"DifferentialExtension(a:Ring)" -> "DifferentialRing()"
-"DifferentialExtension(a:Ring)" -> "PartialDifferentialRing(Symbol)"
-
-"PartialDifferentialRing(Symbol)"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=PDRING"];
-"PartialDifferentialRing(Symbol)" ->
-    "PartialDifferentialRing(a:SetCategory)"
-
-"PartialDifferentialRing(a:SetCategory)" [color=lightblue];
-"PartialDifferentialRing(a:SetCategory)" -> "Ring()"
-
-"DifferentialRing()" [color=lightblue];
-"DifferentialRing()" -> "Ring()"
-
-"Ring()" [color=lightblue];
-"Ring()" -> "Rng()"
-"Ring()" -> "Monoid()"
-"Ring()" -> "LeftModule(a:Ring)"
-
-"Rng()" [color=lightblue];
-"Rng()" -> "ABELGRP..."
-"Rng()" -> "SGROUP..."
-
-"Monoid()" [color=lightblue];
-"Monoid()" -> "SGROUP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LMODULE..."
-
-"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
- [color=lightblue];
-"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
-  -> "BiModule(a:Ring,b:Ring)"
-"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
-  -> "HOAGG..."
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"FRETRCT..." [color=lightblue];
-"FLINEXP..." [color=lightblue];
-"SGROUP..." [color=lightblue];
-"LMODULE..." [color=lightblue];
-"HOAGG..." [color=lightblue];
-"ABELGRP..." [color=lightblue];
-
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{UnivariateTaylorSeriesCategory}{UTSCAT}
-\pagepic{ps/v102univariatetaylorseriescategory.ps}{UTSCAT}{0.60}
-
-{\bf See:}\\
-\pagefrom{RadicalCategory}{RADCAT}
-\pagefrom{TranscendentalFunctionCategory}{TRANFUN}
-\pagefrom{UnivariatePowerSeriesCategory}{UPSCAT}
-
-{\bf Exports:}\\
-\begin{tabular}{llll}
-\cross{UTSCAT}{0} &
-\cross{UTSCAT}{1} &
-\cross{UTSCAT}{acos} &
-\cross{UTSCAT}{acosh} \\
-\cross{UTSCAT}{acot} &
-\cross{UTSCAT}{acoth} &
-\cross{UTSCAT}{acsc} &
-\cross{UTSCAT}{acsch} \\
-\cross{UTSCAT}{approximate} &
-\cross{UTSCAT}{asec} &
-\cross{UTSCAT}{asech} &
-\cross{UTSCAT}{asin} \\
-\cross{UTSCAT}{asinh} &
-\cross{UTSCAT}{associates?} &
-\cross{UTSCAT}{atan} &
-\cross{UTSCAT}{atanh} \\
-\cross{UTSCAT}{center} &
-\cross{UTSCAT}{characteristic} &
-\cross{UTSCAT}{charthRoot} &
-\cross{UTSCAT}{coefficient} \\
-\cross{UTSCAT}{coefficients} &
-\cross{UTSCAT}{coerce} &
-\cross{UTSCAT}{complete} &
-\cross{UTSCAT}{cos} \\
-\cross{UTSCAT}{cosh} &
-\cross{UTSCAT}{cot} &
-\cross{UTSCAT}{coth} &
-\cross{UTSCAT}{csc} \\
-\cross{UTSCAT}{csch} &
-\cross{UTSCAT}{D} &
-\cross{UTSCAT}{degree} &
-\cross{UTSCAT}{differentiate} \\
-\cross{UTSCAT}{eval} &
-\cross{UTSCAT}{exp} &
-\cross{UTSCAT}{exquo} &
-\cross{UTSCAT}{extend} \\
-\cross{UTSCAT}{hash} &
-\cross{UTSCAT}{integrate} &
-\cross{UTSCAT}{latex} &
-\cross{UTSCAT}{leadingCoefficient} \\
-\cross{UTSCAT}{leadingMonomial} &
-\cross{UTSCAT}{log} &
-\cross{UTSCAT}{map} &
-\cross{UTSCAT}{monomial} \\
-\cross{UTSCAT}{monomial?} &
-\cross{UTSCAT}{multiplyCoefficients} &
-\cross{UTSCAT}{multiplyExponents} &
-\cross{UTSCAT}{nthRoot} \\
-\cross{UTSCAT}{one?} &
-\cross{UTSCAT}{order} &
-\cross{UTSCAT}{pi} &
-\cross{UTSCAT}{pole?} \\
-\cross{UTSCAT}{polynomial} &
-\cross{UTSCAT}{quoByVar} &
-\cross{UTSCAT}{recip} &
-\cross{UTSCAT}{reductum} \\
-\cross{UTSCAT}{sample} &
-\cross{UTSCAT}{sec} &
-\cross{UTSCAT}{sech} &
-\cross{UTSCAT}{series} \\
-\cross{UTSCAT}{sin} &
-\cross{UTSCAT}{sinh} &
-\cross{UTSCAT}{sqrt} &
-\cross{UTSCAT}{subtractIfCan} \\
-\cross{UTSCAT}{tan} &
-\cross{UTSCAT}{tanh} &
-\cross{UTSCAT}{terms} &
-\cross{UTSCAT}{truncate} \\
-\cross{UTSCAT}{unit?} &
-\cross{UTSCAT}{unitCanonical} &
-\cross{UTSCAT}{unitNormal} &
-\cross{UTSCAT}{variable} \\
-\cross{UTSCAT}{variables} &
-\cross{UTSCAT}{zero?} &
-\cross{UTSCAT}{?*?} &
-\cross{UTSCAT}{?**?} \\
-\cross{UTSCAT}{?+?} &
-\cross{UTSCAT}{?-?} &
-\cross{UTSCAT}{-?} &
-\cross{UTSCAT}{?=?} \\
-\cross{UTSCAT}{?\^{}?} &
-\cross{UTSCAT}{?\~{}=?} &
-\cross{UTSCAT}{?/?} &
-\cross{UTSCAT}{?.?} \\
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{UTSCAT}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{UTSCAT}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{UTSCAT}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\item if \#1 has IntegralDomain then noZeroDivisors where
-{\bf \cross{UTSCAT}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item if \#1 has CommutativeRing then commutative(``*'') where
-{\bf \cross{UTSCAT}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- coefficients : % -> Stream Coef      
- integrate : (%,Symbol) -> % 
-     if Coef has ACFS INT 
-     and Coef has PRIMCAT 
-     and Coef has TRANFUN 
-     and Coef has ALGEBRA FRAC INT 
-     or Coef has variables: Coef -> List Symbol 
-     and Coef has integrate: (Coef,Symbol) -> Coef 
-     and Coef has ALGEBRA FRAC INT
- integrate : % -> % if Coef has ALGEBRA FRAC INT
- multiplyCoefficients : ((Integer -> Coef),%) -> %
- polynomial : (%,NonNegativeInteger,NonNegativeInteger) -> Polynomial Coef
- polynomial : (%,NonNegativeInteger) -> Polynomial Coef
- quoByVar : % -> %                    
- series : Stream Coef -> %            
- series : Stream Record(k: NonNegativeInteger,c: Coef) -> %
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- acos : % -> % if Coef has ALGEBRA FRAC INT
- acosh : % -> % if Coef has ALGEBRA FRAC INT
- acot : % -> % if Coef has ALGEBRA FRAC INT
- acoth : % -> % if Coef has ALGEBRA FRAC INT
- acsc : % -> % if Coef has ALGEBRA FRAC INT
- acsch : % -> % if Coef has ALGEBRA FRAC INT
- asec : % -> % if Coef has ALGEBRA FRAC INT
- asech : % -> % if Coef has ALGEBRA FRAC INT
- asin : % -> % if Coef has ALGEBRA FRAC INT
- asinh : % -> % if Coef has ALGEBRA FRAC INT
- atan : % -> % if Coef has ALGEBRA FRAC INT
- atanh : % -> % if Coef has ALGEBRA FRAC INT
- coerce : % -> OutputForm             
- cos : % -> % if Coef has ALGEBRA FRAC INT
- cosh : % -> % if Coef has ALGEBRA FRAC INT
- cot : % -> % if Coef has ALGEBRA FRAC INT
- coth : % -> % if Coef has ALGEBRA FRAC INT
- csc : % -> % if Coef has ALGEBRA FRAC INT
- csch : % -> % if Coef has ALGEBRA FRAC INT
- exp : % -> % if Coef has ALGEBRA FRAC INT
- log : % -> % if Coef has ALGEBRA FRAC INT
- sinh : % -> % if Coef has ALGEBRA FRAC INT
- sec : % -> % if Coef has ALGEBRA FRAC INT
- sech : % -> % if Coef has ALGEBRA FRAC INT
- sin : % -> % if Coef has ALGEBRA FRAC INT
- tan : % -> % if Coef has ALGEBRA FRAC INT
- tanh : % -> % if Coef has ALGEBRA FRAC INT
- zero? : % -> Boolean                 
- ?**? : (%,Coef) -> % if Coef has FIELD
- ?**? : (%,%) -> % if Coef has ALGEBRA FRAC INT
- ?**? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ 0 : () -> % if R has CABMON          
+ subtractIfCan : (%,%) -> Union(%,"failed") if R has CABMON
+ zero? : % -> Boolean if R has CABMON
+ ?+? : (%,%) -> % if R has ABELSG
+ ?*? : (PositiveInteger,%) -> % if R has ABELSG
+ ?*? : (NonNegativeInteger,%) -> % if R has CABMON
+ ?*? : (Integer,%) -> % if R has RING
+ ?-? : (%,%) -> % if R has RING
+ -? : % -> % if R has RING            
 \end{verbatim}
 
-These exports come from \refto{UnivariatePowerSeriesCategory}(Coef,NNI)\\
-where Coef:Ring and NNI:NonNegativeInteger:
+These exports come from \refto{DifferentialExtension}(R:Ring):
 \begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- approximate : (%,NonNegativeInteger) -> Coef 
-     if Coef has **: (Coef,NonNegativeInteger) -> Coef 
-     and Coef has coerce: Symbol -> Coef
- associates? : (%,%) -> Boolean if Coef has INTDOM
- center : % -> Coef
- characteristic : () -> NonNegativeInteger
- charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
- coefficient : (%,NonNegativeInteger) -> Coef
- coerce : Coef -> % if Coef has COMRING
- coerce : % -> % if Coef has INTDOM
- coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
- coerce : Integer -> %
- complete : % -> %
- D : % -> % if Coef has *: (NonNegativeInteger,Coef) -> Coef
+ 1 : () -> % if R has RING
+ D : (%,(R -> R)) -> % if R has RING
+ D : (%,(R -> R),NonNegativeInteger) -> % if R has RING
+ D : % -> % if and(has(R,DifferentialRing),has(R,Ring))
  D : (%,NonNegativeInteger) -> % 
-     if Coef has *: (NonNegativeInteger,Coef) -> Coef
- D : (%,Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- D : (%,List Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- D : (%,Symbol,NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+   if and(has(R,DifferentialRing),has(R,Ring))
+ differentiate : (%,NonNegativeInteger) -> % 
+   if and(has(R,DifferentialRing),has(R,Ring))
  D : (%,List Symbol,List NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- differentiate : (%,List Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- differentiate : (%,Symbol,NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ D : (%,Symbol,NonNegativeInteger) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ D : (%,List Symbol) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ D : (%,Symbol) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
  differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- differentiate : (%,Symbol) -> % 
-     if Coef has PDRING SYMBOL 
-     and Coef has *: (NonNegativeInteger,Coef) -> Coef
- differentiate : (%,NonNegativeInteger) -> % 
-     if Coef has *: (NonNegativeInteger,Coef) -> Coef
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ differentiate : (%,Symbol,NonNegativeInteger) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ differentiate : (%,List Symbol) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
  differentiate : % -> % 
-     if Coef has *: (NonNegativeInteger,Coef) -> Coef
- degree : % -> NonNegativeInteger     
- extend : (%,NonNegativeInteger) -> %
- exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
- eval : (%,Coef) -> Stream Coef 
-     if Coef has **: (Coef,NonNegativeInteger) -> Coef
- hash : % -> SingleInteger
- latex : % -> String                  
- leadingCoefficient : % -> Coef
- leadingMonomial : % -> %             
- map : ((Coef -> Coef),%) -> %
- monomial : (Coef,NonNegativeInteger) -> %
- monomial : (%,SingletonAsOrderedSet,NonNegativeInteger) -> %
- monomial : (%,List SingletonAsOrderedSet,List NonNegativeInteger) -> %
- monomial? : % -> Boolean             
- multiplyExponents : (%,PositiveInteger) -> %
- one? : % -> Boolean
- order : % -> NonNegativeInteger      
- order : (%,NonNegativeInteger) -> NonNegativeInteger
- pole? : % -> Boolean
- recip : % -> Union(%,"failed")
- reductum : % -> %                    
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- terms : % -> Stream Record(k: NonNegativeInteger,c: Coef)
- truncate : (%,NonNegativeInteger,NonNegativeInteger) -> %
- truncate : (%,NonNegativeInteger) -> %
- unit? : % -> Boolean if Coef has INTDOM
- unitCanonical : % -> % if Coef has INTDOM
- unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
-     if Coef has INTDOM
- variable : % -> Symbol
- variables : % -> List SingletonAsOrderedSet
- ?^? : (%,NonNegativeInteger) -> %
- ?+? : (%,%) -> %                     
- ?=? : (%,%) -> Boolean
- ?~=? : (%,%) -> Boolean
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (%,%) -> %                     
- ?-? : (%,%) -> %
- ?**? : (%,PositiveInteger) -> %
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
- ?*? : (Integer,%) -> %
- ?*? : (Coef,%) -> %                  
- ?*? : (%,Coef) -> %
- ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
- ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
- ?/? : (%,Coef) -> % if Coef has FIELD
- -? : % -> %                          
- ?.? : (%,%) -> % if NonNegativeInteger has SGROUP
- ?.? : (%,NonNegativeInteger) -> Coef
-\end{verbatim}
-
-These exports come from \refto{TranscendentalFunctionCategory}():
-\begin{verbatim}
- pi : () -> % if Coef has ALGEBRA FRAC INT
+   if and(has(R,DifferentialRing),has(R,Ring))
+ differentiate : (%,(R -> R),NonNegativeInteger) -> % 
+   if R has RING
+ differentiate : (%,Symbol) -> % 
+   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
+ one? : % -> Boolean if R has RING
+ recip : % -> Union(%,"failed") if R has RING
+ ?*? : (%,%) -> % if R has RING
+ ?**? : (%,PositiveInteger) -> % if R has RING
+ ?**? : (%,NonNegativeInteger) -> % if R has RING
+ ?^? : (%,PositiveInteger) -> % if R has RING
+ ?^? : (%,NonNegativeInteger) -> % if R has RING
 \end{verbatim}
 
-These exports come from \refto{RadicalCategory}():
+These exports come from \refto{FullyLinearlyExplicitRingOver}(R:Ring):
 \begin{verbatim}
- nthRoot : (%,Integer) -> % if Coef has ALGEBRA FRAC INT
- sqrt : % -> % if Coef has ALGEBRA FRAC INT
+ reducedSystem :
+   (Matrix %,Vector %) -> 
+     Record(mat: Matrix Integer,vec: Vector Integer) 
+       if and(has(R,LinearlyExplicitRingOver Integer),has(R,Ring))
+ reducedSystem : Matrix % -> Matrix Integer 
+   if and(has(R,LinearlyExplicitRingOver Integer),has(R,Ring))
 \end{verbatim}
 
-<<category UTSCAT UnivariateTaylorSeriesCategory>>=
-)abbrev category UTSCAT UnivariateTaylorSeriesCategory
-++ Author: Clifton J. Williamson
-++ Date Created: 21 December 1989
-++ Date Last Updated: 26 May 1994
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: series, Taylor, linebacker
-++ Examples:
-++ References:
-++ Description:
-++   \spadtype{UnivariateTaylorSeriesCategory} is the category of Taylor
-++   series in one variable.
-UnivariateTaylorSeriesCategory(Coef): Category == Definition where
-  Coef  : Ring
-  I    ==> Integer
-  L    ==> List
-  NNI  ==> NonNegativeInteger
-  OUT  ==> OutputForm
-  RN   ==> Fraction Integer
-  STTA ==> StreamTaylorSeriesOperations Coef
-  STTF ==> StreamTranscendentalFunctions Coef
-  STNC ==> StreamTranscendentalFunctionsNonCommutative Coef
-  Term ==> Record(k:NNI,c:Coef)
-
-  Definition ==> UnivariatePowerSeriesCategory(Coef,NNI) with
-
-    series: Stream Term -> %
-      ++ \spad{series(st)} creates a series from a stream of non-zero terms,
-      ++ where a term is an exponent-coefficient pair.  The terms in the
-      ++ stream should be ordered by increasing order of exponents.
-    coefficients: % -> Stream Coef
-      ++ \spad{coefficients(a0 + a1 x + a2 x**2 + ...)} returns a stream
-      ++ of coefficients: \spad{[a0,a1,a2,...]}. The entries of the stream
-      ++ may be zero.
-    series: Stream Coef -> %
-      ++ \spad{series([a0,a1,a2,...])} is the Taylor series
-      ++ \spad{a0 + a1 x + a2 x**2 + ...}.
-    quoByVar: % -> %
-      ++ \spad{quoByVar(a0 + a1 x + a2 x**2 + ...)}
-      ++ returns \spad{a1 + a2 x + a3 x**2 + ...}
-      ++ Thus, this function substracts the constant term and divides by
-      ++ the series variable.  This function is used when Laurent series
-      ++ are represented by a Taylor series and an order.
-    multiplyCoefficients: (I -> Coef,%) -> %
-      ++ \spad{multiplyCoefficients(f,sum(n = 0..infinity,a[n] * x**n))}
-      ++ returns \spad{sum(n = 0..infinity,f(n) * a[n] * x**n)}.
-      ++ This function is used when Laurent series are represented by
-      ++ a Taylor series and an order.
-    polynomial: (%,NNI) -> Polynomial Coef
-      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
-      ++ of all terms of f of degree \spad{<= k}.
-    polynomial: (%,NNI,NNI) -> Polynomial Coef
-      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
-      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
-
-    if Coef has Field then
-      "**": (%,Coef) -> %
-        ++ \spad{f(x) ** a} computes a power of a power series.
-        ++ When the coefficient ring is a field, we may raise a series
-        ++ to an exponent from the coefficient ring provided that the
-        ++ constant coefficient of the series is 1.
-
-    if Coef has Algebra Fraction Integer then
-      integrate: % -> %
-        ++ \spad{integrate(f(x))} returns an anti-derivative of the power
-        ++ series \spad{f(x)} with constant coefficient 0.
-        ++ We may integrate a series when we can divide coefficients
-        ++ by integers.
-      if Coef has integrate: (Coef,Symbol) -> Coef and _
-         Coef has variables: Coef -> List Symbol then
-        integrate: (%,Symbol) -> %
-          ++ \spad{integrate(f(x),y)} returns an anti-derivative of the
-          ++ power series \spad{f(x)} with respect to the variable \spad{y}.
-      if Coef has TranscendentalFunctionCategory and _
-         Coef has PrimitiveFunctionCategory and _
-         Coef has AlgebraicallyClosedFunctionSpace Integer then
-        integrate: (%,Symbol) -> %
-          ++ \spad{integrate(f(x),y)} returns an anti-derivative of
-          ++ the power series \spad{f(x)} with respect to the variable
-          ++ \spad{y}.
-      RadicalCategory
-        --++ We provide rational powers when we can divide coefficients
-        --++ by integers.
-      TranscendentalFunctionCategory
-        --++ We provide transcendental functions when we can divide
-        --++ coefficients by integers.
-
-   add
-
-    zero? x ==
-      empty? (coefs := coefficients x) => true
-      (zero? frst coefs) and (empty? rst coefs) => true
-      false
-
---% OutputForms
-
---  We provide defaulr output functions on UTSCAT using the functions
---  'coefficients', 'center', and 'variable'.
-
-    factorials?: () -> Boolean
-    -- check a global Lisp variable
-    factorials?() == false
-
-    termOutput: (I,Coef,OUT) -> OUT
-    termOutput(k,c,vv) ==
-    -- creates a term c * vv ** k
-      k = 0 => c :: OUT
-      mon := (k = 1 => vv; vv ** (k :: OUT))
---       if factorials?() and k > 1 then
---         c := factorial(k)$IntegerCombinatoricFunctions * c
---         mon := mon / hconcat(k :: OUT,"!" :: OUT)
-      c = 1 => mon
-      c = -1 => -mon
-      (c :: OUT) * mon
-
-    showAll?: () -> Boolean
-    -- check a global Lisp variable
-    showAll?() == true
-
-    coerce(p:%):OUT ==
-      empty? (uu := coefficients p) => (0$Coef) :: OUT
-      var := variable p; cen := center p
-      vv :=
-        zero? cen => var :: OUT
-        paren(var :: OUT - cen :: OUT)
-      n : NNI ; count : NNI := _$streamCount$Lisp
-      l : L OUT := empty()
-      for n in 0..count while not empty? uu repeat
-        if frst(uu) ^= 0 then
-          l := concat(termOutput(n :: I,frst uu,vv),l)
-        uu := rst uu
-      if showAll?() then
-        for n in (count + 1).. while explicitEntries? uu and _
-               not eq?(uu,rst uu) repeat
-          if frst(uu) ^= 0 then
-            l := concat(termOutput(n :: I,frst uu,vv),l)
-          uu := rst uu
-      l :=
-        explicitlyEmpty? uu => l
-        eq?(uu,rst uu) and frst uu = 0 => l
-        concat(prefix("O" :: OUT,[vv ** (n :: OUT)]),l)
-      empty? l => (0$Coef) :: OUT
-      reduce("+",reverse_! l)
-
-    if Coef has Field then
-      (x:%) ** (r:Coef) == series power(r,coefficients x)$STTA
-
-    if Coef has Algebra Fraction Integer then
-      if Coef has CommutativeRing then
-        (x:%) ** (y:%)    == series(coefficients x **$STTF coefficients y)
-
-        (x:%) ** (r:RN)   == series powern(r,coefficients x)$STTA
-
-        exp x == series exp(coefficients x)$STTF
-
-        log x == series log(coefficients x)$STTF
-
-        sin x == series sin(coefficients x)$STTF
-
-        cos x == series cos(coefficients x)$STTF
-
-        tan x == series tan(coefficients x)$STTF
-
-        cot x == series cot(coefficients x)$STTF
-
-        sec x == series sec(coefficients x)$STTF
-
-        csc x == series csc(coefficients x)$STTF
-
-        asin x == series asin(coefficients x)$STTF
-
-        acos x == series acos(coefficients x)$STTF
-
-        atan x == series atan(coefficients x)$STTF
-
-        acot x == series acot(coefficients x)$STTF
-
-        asec x == series asec(coefficients x)$STTF
-
-        acsc x == series acsc(coefficients x)$STTF
-
-        sinh x == series sinh(coefficients x)$STTF
-
-        cosh x == series cosh(coefficients x)$STTF
-
-        tanh x == series tanh(coefficients x)$STTF
-
-        coth x == series coth(coefficients x)$STTF
-
-        sech x == series sech(coefficients x)$STTF
-
-        csch x == series csch(coefficients x)$STTF
-
-        asinh x == series asinh(coefficients x)$STTF
-
-        acosh x == series acosh(coefficients x)$STTF
-
-        atanh x == series atanh(coefficients x)$STTF
-
-        acoth x == series acoth(coefficients x)$STTF
-
-        asech x == series asech(coefficients x)$STTF
-
-        acsch x == series acsch(coefficients x)$STTF
-
-      else
-        (x:%) ** (y:%) == series(coefficients x **$STNC coefficients y)
-
-        (x:%) ** (r:RN) ==
-          coefs := coefficients x
-          empty? coefs =>
-            positive? r => 0
-            zero? r => error "0**0 undefined"
-            error "0 raised to a negative power"
---          not one? frst coefs =>
-          not (frst coefs = 1) =>
-            error "**: constant coefficient should be 1"
-          coefs := concat(0,rst coefs)
-          onePlusX := monom(1,0)$STTA + $STTA monom(1,1)$STTA
-          ratPow := powern(r,onePlusX)$STTA
-          series compose(ratPow,coefs)$STTA
-
-        exp x == series exp(coefficients x)$STNC
-
-        log x == series log(coefficients x)$STNC
-
-        sin x == series sin(coefficients x)$STNC
-
-        cos x == series cos(coefficients x)$STNC
-
-        tan x == series tan(coefficients x)$STNC
-
-        cot x == series cot(coefficients x)$STNC
-
-        sec x == series sec(coefficients x)$STNC
-
-        csc x == series csc(coefficients x)$STNC
-
-        asin x == series asin(coefficients x)$STNC
-
-        acos x == series acos(coefficients x)$STNC
-
-        atan x == series atan(coefficients x)$STNC
-
-        acot x == series acot(coefficients x)$STNC
-
-        asec x == series asec(coefficients x)$STNC
-
-        acsc x == series acsc(coefficients x)$STNC
-
-        sinh x == series sinh(coefficients x)$STNC
-
-        cosh x == series cosh(coefficients x)$STNC
-
-        tanh x == series tanh(coefficients x)$STNC
-
-        coth x == series coth(coefficients x)$STNC
-
-        sech x == series sech(coefficients x)$STNC
-
-        csch x == series csch(coefficients x)$STNC
-
-        asinh x == series asinh(coefficients x)$STNC
-
-        acosh x == series acosh(coefficients x)$STNC
-
-        atanh x == series atanh(coefficients x)$STNC
-
-        acoth x == series acoth(coefficients x)$STNC
-
-        asech x == series asech(coefficients x)$STNC
-
-        acsch x == series acsch(coefficients x)$STNC
-
-@
-<<UTSCAT.dotabb>>=
-"UTSCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=UTSCAT"];
-"UTSCAT" -> "UPSCAT"
-
-@
-<<UTSCAT.dotfull>>=
-"UnivariateTaylorSeriesCategory(a:Ring)" 
- [color=lightblue,href="bookvol10.2.pdf#nameddest=UTSCAT"];
-"UnivariateTaylorSeriesCategory(a:Ring)" ->
-    "UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)"
-
-@
-<<UTSCAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"UnivariateTaylorSeriesCategory(a:Ring)" [color=lightblue];
-"UnivariateTaylorSeriesCategory(a:Ring)" ->
-    "UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)"
-
-"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" 
- [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
-"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" -> 
-    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
-
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
- [color=lightblue];
-"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
- "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
-
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
- [color=seagreen];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
-  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
-
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
- [color=lightblue];
-"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
-    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
-
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "BIMODULE..."
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "IntegralDomain()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CharacteristicNonZero()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "CommutativeRing()"
-"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
-    "Algebra(Fraction(Integer))"
-
-"IntegralDomain()" [color=lightblue];
-"IntegralDomain()" -> "CommutativeRing()"
-"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
-"IntegralDomain()" -> "EntireRing()"
-
-"EntireRing()" [color=lightblue];
-"EntireRing()" -> "RING..."
-"EntireRing()" -> "BIMODULE..."
-
-"CharacteristicNonZero()"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
-"CharacteristicNonZero()" -> "RING..."
-
-"Algebra(Fraction(Integer))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
-
-"Algebra(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
-"Algebra(a:CommutativeRing)" -> "RING..."
-"Algebra(a:CommutativeRing)" -> "MODULE..."
-
-"CommutativeRing()" [color=lightblue];
-"CommutativeRing()" -> "RING..."
-"CommutativeRing()" -> "BIMODULE..."
-
-"BIMODULE..." [color=lightblue];
-"RING..." [color=lightblue];
-"MODULE..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{VectorSpace}{VSPACE}
-\pagepic{ps/v102vectorspace.ps}{VSPACE}{1.00}
-
-{\bf See:}\\
-\pageto{ExtensionField}{XF}
-\pagefrom{Module}{MODULE}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{VSPACE}{0} &
-\cross{VSPACE}{coerce} &
-\cross{VSPACE}{dimension} &
-\cross{VSPACE}{hash} &
-\cross{VSPACE}{latex} \\
-\cross{VSPACE}{sample} &
-\cross{VSPACE}{subtractIfCan} &
-\cross{VSPACE}{zero?} &
-\cross{VSPACE}{?\~{}=?} &
-\cross{VSPACE}{?*?} \\
-\cross{VSPACE}{?+?} &
-\cross{VSPACE}{?-?} &
-\cross{VSPACE}{-?} &
-\cross{VSPACE}{?/?} &
-\cross{VSPACE}{?=?} \\
-\end{tabular}
-
-{\bf Attributes exported:}
-\begin{itemize}
-\item {\bf \cross{VSPACE}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{VSPACE}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are directly exported but not implemented:
+These exports come from \refto{Finite}():
 \begin{verbatim}
- dimension : () -> CardinalNumber
+ index : PositiveInteger -> % if R has FINITE
+ lookup : % -> PositiveInteger if R has FINITE
+ random : () -> % if R has FINITE
 \end{verbatim}
 
-These are implemented by this category:
+These exports come from \refto{OrderedRing}():
 \begin{verbatim}
- ?/? : (%,S) -> %
+ abs : % -> % if R has ORDRING
+ max : (%,%) -> % if R has ORDRING or R has OAMONS
+ min : (%,%) -> % if R has ORDRING or R has OAMONS
+ negative? : % -> Boolean if R has ORDRING
+ positive? : % -> Boolean if R has ORDRING
+ sign : % -> Integer if R has ORDRING
+ ?<? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
+ ?<=? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
+ ?>? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
+ ?>=? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
 \end{verbatim}
 
-These exports come from \refto{Module}():
+These exports come from \refto{OrderedAbelianMonoidSup}():
 \begin{verbatim}
- ?*? : (%,S) -> %                     
- 0 : () -> %
- coerce : % -> OutputForm             
- hash : % -> SingleInteger            
- latex : % -> String
- sample : () -> %                     
- subtractIfCan : (%,%) -> Union(%,"failed")
- zero? : % -> Boolean
- ?~=? : (%,%) -> Boolean              
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (S,%) -> %
- ?*? : (Integer,%) -> %               
- ?*? : (PositiveInteger,%) -> %
- ?+? : (%,%) -> %                     
- ?-? : (%,%) -> %
- -? : % -> %                          
- ?=? : (%,%) -> Boolean               
+ sup : (%,%) -> % if R has OAMONS
 \end{verbatim}
 
-<<category VSPACE VectorSpace>>=
-)abbrev category VSPACE VectorSpace
+<<category DIRPCAT DirectProductCategory>>=
+)abbrev category DIRPCAT DirectProductCategory
+-- all direct product category domains must be compiled
+-- without subsumption, set SourceLevelSubset to EQUAL
+--)bo $noSubsumption := true
+ 
+--% DirectProductCategory
+ 
 ++ Author:
 ++ Date Created:
 ++ Date Last Updated:
 ++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ Vector Spaces (not necessarily finite dimensional) over a field.
-
-VectorSpace(S:Field): Category ==  Module(S) with
-    "/"      : (%, S) -> %
-      ++ x/y divides the vector x by the scalar y.
-    dimension: () -> CardinalNumber
-      ++ dimension() returns the dimensionality of the vector space.
-  add
-    (v:% / s:S):% == inv(s) * v
-
-@
-<<VSPACE.dotabb>>=
-"VSPACE"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=VSPACE"];
-"VSPACE" -> "MODULE"
-
-@
-<<VSPACE.dotfull>>=
-"VectorSpace(a:Field)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=VSPACE"];
-"VectorSpace(a:Field)" -> "Module(Field)"
-
-@
-<<VSPACE.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"VectorSpace(a:Field)" [color=lightblue];
-"VectorSpace(a:Field)" -> "Module(Field)"
-
-"Module(Field)" [color=seagreen];
-"Module(Field)" -> "Module(a:CommutativeRing)"
-
-"Module(a:CommutativeRing)" [color=lightblue];
-"Module(a:CommutativeRing)" ->
-  "BiModule(a:CommutativeRing,b:CommutativeRing)"
-
-"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
-"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"ABELGRP..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{XPolynomialsCat}{XPOLYC}
-\pagepic{ps/v102xpolynomialscat.ps}{XPOLYC}{0.50}
-
-{\bf See:}\\
-\pagefrom{XFreeAlgebra}{XFALG}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{XPOLYC}{0} &
-\cross{XPOLYC}{1} &
-\cross{XPOLYC}{characteristic} &
-\cross{XPOLYC}{coef} &
-\cross{XPOLYC}{coerce} \\
-\cross{XPOLYC}{constant} &
-\cross{XPOLYC}{constant?} &
-\cross{XPOLYC}{degree} &
-\cross{XPOLYC}{hash} &
-\cross{XPOLYC}{latex} \\
-\cross{XPOLYC}{lquo} &
-\cross{XPOLYC}{map} &
-\cross{XPOLYC}{maxdeg} &
-\cross{XPOLYC}{mindeg} &
-\cross{XPOLYC}{mindegTerm} \\
-\cross{XPOLYC}{mirror} &
-\cross{XPOLYC}{monom} &
-\cross{XPOLYC}{monomial?} &
-\cross{XPOLYC}{one?} &
-\cross{XPOLYC}{quasiRegular} \\
-\cross{XPOLYC}{quasiRegular?} &
-\cross{XPOLYC}{recip} &
-\cross{XPOLYC}{retract} &
-\cross{XPOLYC}{retractIfCan} &
-\cross{XPOLYC}{rquo} \\
-\cross{XPOLYC}{sample} &
-\cross{XPOLYC}{sh} &
-\cross{XPOLYC}{subtractIfCan} &
-\cross{XPOLYC}{trunc} &
-\cross{XPOLYC}{varList} \\
-\cross{XPOLYC}{zero?} &
-\cross{XPOLYC}{?*?} &
-\cross{XPOLYC}{?**?} &
-\cross{XPOLYC}{?+?} &
-\cross{XPOLYC}{?-?} \\
-\cross{XPOLYC}{-?} &
-\cross{XPOLYC}{?=?} &
-\cross{XPOLYC}{?\^{}?} &
-\cross{XPOLYC}{?\~{}=?} &
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item if Ring has noZeroDivisors then noZeroDivisors where
-{\bf \cross{XPOLYC}{noZeroDivisors}}
-is true if $x * y \ne 0$ implies both x and y are non-zero.
-\item {\bf \cross{XPOLYC}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{XPOLYC}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{XPOLYC}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- degree : % -> NonNegativeInteger
- maxdeg : % -> OrderedFreeMonoid vl
- trunc : (%,NonNegativeInteger) -> %
-\end{verbatim}
-
-These exports come from \refto{Aggregate}():
-\begin{verbatim}
-\end{verbatim}
-
-These exports come from \refto{XFreeAlgebra}(vl:OrderedSet,R:Ring):
-\begin{verbatim}
- 0 : () -> %                          
- 1 : () -> %
- characteristic : () -> NonNegativeInteger
- coef : (%,OrderedFreeMonoid vl) -> R
- coef : (%,%) -> R                    
- coerce : % -> OutputForm             
- coerce : R -> %                      
- coerce : OrderedFreeMonoid vl -> %
- coerce : Integer -> %
- coerce : vl -> %
- constant : % -> R
- constant? : % -> Boolean             
- hash : % -> SingleInteger            
- latex : % -> String
- lquo : (%,OrderedFreeMonoid vl) -> %
- lquo : (%,%) -> %                    
- lquo : (%,vl) -> %
- map : ((R -> R),%) -> %              
- mindeg : % -> OrderedFreeMonoid vl
- mindegTerm : % -> Record(k: OrderedFreeMonoid vl,c: R)
- mirror : % -> %
- monom : (OrderedFreeMonoid vl,R) -> %
- monomial? : % -> Boolean             
- one? : % -> Boolean
- quasiRegular : % -> %                
- quasiRegular? : % -> Boolean
- recip : % -> Union(%,"failed")       
- retract : % -> OrderedFreeMonoid vl
- retractIfCan : % -> Union(OrderedFreeMonoid vl,"failed")
- rquo : (%,OrderedFreeMonoid vl) -> %
- rquo : (%,%) -> %
- rquo : (%,vl) -> %                   
- sample : () -> %
- sh : (%,NonNegativeInteger) -> % if R has COMRING
- sh : (%,%) -> % if R has COMRING
- subtractIfCan : (%,%) -> Union(%,"failed")
- varList : % -> List vl               
- zero? : % -> Boolean
- ?+? : (%,%) -> %
- ?=? : (%,%) -> Boolean               
- ?~=? : (%,%) -> Boolean              
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %
- ?*? : (Integer,%) -> %               
- ?*? : (%,%) -> %
- ?*? : (R,%) -> %                     
- ?*? : (%,R) -> %
- ?-? : (%,%) -> %                     
- -? : % -> %
- ?**? : (%,PositiveInteger) -> %      
- ?**? : (%,NonNegativeInteger) -> %
- ?^? : (%,NonNegativeInteger) -> %
- ?^? : (%,PositiveInteger) -> %
- ?*? : (vl,%) -> %                    
-\end{verbatim}
-
-These exports come from \refto{SetCategory}():
-\begin{verbatim}
-\end{verbatim}
-
-<<category XPOLYC XPolynomialsCat>>=
-)abbrev category XPOLYC XPolynomialsCat
-++ Author: Michel Petitot petitot@lifl.fr
-++ Date Created: 91
-++ Date Last Updated: 7 Juillet 92
-++ Fix History: compilation v 2.1 le 13 dec 98
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
+++ Related Constructors: DirectProduct
+++ Also See: VectorCategory
 ++ AMS Classifications:
 ++ Keywords:
 ++ References:
 ++ Description:
-++   The Category of polynomial rings with non-commutative variables.
-++   The coefficient ring may be non-commutative too. 
-++   However coefficients commute with vaiables.
-++ Author: Michel Petitot (petitot@lifl.fr)
+++   This category represents a finite cartesian product of a given type.
+++ Many categorical properties are preserved under this construction.
+ 
+DirectProductCategory(dim:NonNegativeInteger, R:Type): Category ==
+  Join(IndexedAggregate(Integer, R), CoercibleTo Vector R) with
+         finiteAggregate
+           ++ attribute to indicate an aggregate of finite size
+         directProduct: Vector R -> %
+           ++ directProduct(v) converts the vector v to become
+           ++ a direct product. Error: if the length of v is
+           ++ different from dim.
+         if R has SetCategory then FullyRetractableTo R
+         if R has Ring then
+           BiModule(R, R)
+           DifferentialExtension R
+           FullyLinearlyExplicitRingOver R
+           unitVector: PositiveInteger -> %
+             ++ unitVector(n) produces a vector with 1 in position n and
+             ++ zero elsewhere.
+           dot: (%, %) -> R
+             ++ dot(x,y) computes the inner product of the vectors x and y.
+         if R has AbelianSemiGroup then AbelianSemiGroup
+         if R has CancellationAbelianMonoid then CancellationAbelianMonoid
+         if R has Monoid then
+            Monoid
+           _* : (R, %) -> %
+             ++ r * y multiplies the element r times each component of the
+             ++ vector y.
+           _* : (%, R) -> %
+             ++ y*r multiplies each component of the vector y by the element r.
+         if R has Finite then Finite
+         if R has CommutativeRing then
+           Algebra R
+           CommutativeRing
+         if R has unitsKnown then unitsKnown
+         if R has OrderedRing then OrderedRing
+         if R has OrderedAbelianMonoidSup then OrderedAbelianMonoidSup
+         if R has Field then VectorSpace R
+ add
+      if R has Ring then
+        equation2R: Vector % -> Matrix R
+ 
+        coerce(n:Integer):%          == n::R::%
 
-XPolynomialsCat(vl:OrderedSet,R:Ring):Category == Export where
-  WORD ==> OrderedFreeMonoid(vl)
+        characteristic()             == characteristic()$R
 
-  Export == XFreeAlgebra(vl,R) with
-    maxdeg: % -> WORD 
-      ++ \spad{maxdeg(p)} returns the greatest leading word in the 
-      ++ support of \spad{p}.
-    degree: % -> NonNegativeInteger 
-      ++ \spad{degree(p)} returns the degree of \spad{p}. 
-      ++  Note that the degree of a word is its length. 
-    trunc : (% , NonNegativeInteger) -> %
-      ++  \spad{trunc(p,n)} returns the polynomial \spad{p} truncated 
-      ++ at order \spad{n}.
+        differentiate(z:%, d:R -> R) == map(d, z)
+ 
+        equation2R v ==
+          ans:Matrix(R) := new(dim, #v, 0)
+          for i in minRowIndex ans .. maxRowIndex ans repeat
+            for j in minColIndex ans .. maxColIndex ans repeat
+              qsetelt_!(ans, i, j, qelt(qelt(v, j), i))
+          ans
+ 
+        reducedSystem(m:Matrix %):Matrix(R) ==
+          empty? m => new(0, 0, 0)
+          reduce(vertConcat, [equation2R row(m, i)
+                 for i in minRowIndex m .. maxRowIndex m])$List(Matrix R)
+ 
+        reducedSystem(m:Matrix %, v:Vector %):
+          Record(mat:Matrix R, vec:Vector R) ==
+            vh:Vector(R) :=
+              empty? v => empty()
+              rh := reducedSystem(v::Matrix %)@Matrix(R)
+              column(rh, minColIndex rh)
+            [reducedSystem(m)@Matrix(R), vh]
+ 
+      if R has Finite then size == size$R ** dim
+ 
+      if R has Field then
+        x / b       == x * inv b
 
+        dimension() == dim::CardinalNumber
+ 
 @
-<<XPOLYC.dotabb>>=
-"XPOLYC"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
-"XPOLYC" -> "XFALG"
+<<DIRPCAT.dotabb>>=
+"DIRPCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=DIRPCAT"];
+"DIRPCAT" -> "IXAGG"
+"DIRPCAT" -> "KOERCE"
+"DIRPCAT" -> "FRETRCT"
+"DIRPCAT" -> "BMODULE"
+"DIRPCAT" -> "DIFEXT"
+"DIRPCAT" -> "FLINEXP"
+"DIRPCAT" -> "FINITE"
+"DIRPCAT" -> "ORDRING"
+"DIRPCAT" -> "OAMONS"
 
 @
-<<XPOLYC.dotfull>>=
-"XPolynomialsCat(a:OrderedRing,b:Ring)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
-"XPolynomialsCat(a:OrderedRing,b:Ring)" -> 
-   "XFreeAlgebra(a:OrderedSet,b:Ring)"
+<<DIRPCAT.dotfull>>=
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=DIRPCAT"];
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "IndexedAggregate(a:SetCategory,b:Type)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "CoercibleTo(a:Type)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "FullyRetractableTo(a:Type)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "BiModule(a:Ring,b:Ring)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "DifferentialExtension(a:Ring)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "FullyLinearlyExplicitRingOver(a:Ring)"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "Finite()"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "OrderedRing()"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)"
+  -> "OrderedAbelianMonoidSup()"
 
 @
-<<XPOLYC.dotpic>>=
+<<DIRPCAT.dotpic>>=
 digraph pic {
  fontsize=10;
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"XPolynomialsCat(a:OrderedRing,b:Ring)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
-"XPolynomialsCat(a:OrderedRing,b:Ring)" -> 
-   "XFreeAlgebra(a:OrderedSet,b:Ring)"
-
-"XFreeAlgebra(a:OrderedSet,b:Ring)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=XFALG"];
-"XFreeAlgebra(a:OrderedSet,b:Ring)" -> "Ring()"
-"XFreeAlgebra(a:OrderedSet,b:Ring)" -> "XAlgebra(a:Ring)"
-"XFreeAlgebra(a:OrderedSet,b:Ring)" -> 
-    "RetractableTo(OrderedFreeMonoid(OrderedSet))"
-
-"RetractableTo(OrderedFreeMonoid(OrderedSet))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
-"RetractableTo(OrderedFreeMonoid(OrderedSet))" -> "RetractableTo(a:Type)"
-
-"XAlgebra(a:Ring)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=XALG"];
-"XAlgebra(a:Ring)" -> "Ring()"
-"XAlgebra(a:Ring)" -> "BiModule(a:Ring,b:Ring)"
-
-"Ring()" [color=lightblue];
-"Ring()" -> "Rng()"
-"Ring()" -> "Monoid()"
-"Ring()" -> "LeftModule(a:Ring)"
-
-"BiModule(a:Ring,b:Ring)" [color=lightblue];
-"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
-"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
-
-"RightModule(a:Ring)" [color=seagreen];
-"RightModule(a:Ring)" -> "RightModule(a:Rng)"
-
-"RightModule(a:Rng)" [color=lightblue];
-"RightModule(a:Rng)" -> "ABELGRP..."
-
-"Rng()" [color=lightblue];
-"Rng()" -> "ABELGRP..."
-"Rng()" -> "SemiGroup()"
-
-"Monoid()" [color=lightblue];
-"Monoid()" -> "SemiGroup()"
-
-"LeftModule(a:Ring)" [color=seagreen];
-"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
-
-"LeftModule(a:Rng)" [color=lightblue];
-"LeftModule(a:Rng)" -> "ABELGRP..."
-
-"SemiGroup()" [color=lightblue];
-"SemiGroup()" -> "SETCAT..."
-"SemiGroup()" -> "REPSQ..."
-
-"RetractableTo(a:Type)" [color=lightblue];
-"RetractableTo(a:Type)" -> "Category"
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" [color=lightblue];
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "BMODULE..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "KOERCE..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "DIFEXT..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FINITE..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FLINEXP..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FRETRCT..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "IXAGG..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "OAMONS..."
+"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "ORDRING..."
 
-"Category" [color=lightblue];
+"BMODULE..." [color=lightblue];
+"KOERCE..." [color=lightblue];
+"DIFEXT..." [color=lightblue];
+"FINITE..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+"IXAGG..." [color=lightblue];
+"OAMONS..." [color=lightblue];
+"ORDRING..." [color=lightblue];
 
-"REPSQ..." [color="#00EE00"];
-"SETCAT..." [color=lightblue];
-"ABELGRP..." [color=lightblue];
 }
 
 @
-\chapter{Category Layer 12}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{DivisionRing}{DIVRING}
 \pagepic{ps/v102divisionring.ps}{DIVRING}{0.65}
@@ -34319,9 +34030,6 @@ These exports come from \refto{Algebra}(a:IntegralDomain):
  coerce : % -> %                      
 \end{verbatim}
 
-TPDHERE: Note that none of the exports of EntireRing are needed.
-Perhaps this can be eliminated.
-
 <<category INTDOM IntegralDomain>>=
 )abbrev category INTDOM IntegralDomain
 ++ Author:
@@ -34666,7 +34374,2002 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 13}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{OctonionCategory}{OC}
+\pagepic{ps/v102octonioncategory.ps}{OC}{1.00}
+
+{\bf See:}\\
+\pagefrom{Algebra}{ALGEBRA}
+\pagefrom{FullyEvalableOver}{FEVALAB}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{OC}{0} &
+\cross{OC}{1} &
+\cross{OC}{abs} &
+\cross{OC}{characteristic} &
+\cross{OC}{charthRoot} \\
+\cross{OC}{coerce} &
+\cross{OC}{conjugate} &
+\cross{OC}{convert} &
+\cross{OC}{eval} &
+\cross{OC}{hash} \\
+\cross{OC}{imagE} &
+\cross{OC}{imagI} &
+\cross{OC}{imagJ} &
+\cross{OC}{imagK} &
+\cross{OC}{imagi} \\
+\cross{OC}{imagj} &
+\cross{OC}{imagk} &
+\cross{OC}{index} &
+\cross{OC}{inv} &
+\cross{OC}{latex} \\
+\cross{OC}{lookup} &
+\cross{OC}{map} &
+\cross{OC}{max} &
+\cross{OC}{min} &
+\cross{OC}{norm} \\
+\cross{OC}{octon} &
+\cross{OC}{one?} &
+\cross{OC}{random} &
+\cross{OC}{rational} &
+\cross{OC}{rational?} \\
+\cross{OC}{rationalIfCan} &
+\cross{OC}{real} &
+\cross{OC}{recip} &
+\cross{OC}{retract} &
+\cross{OC}{retractIfCan} \\
+\cross{OC}{sample} &
+\cross{OC}{size} &
+\cross{OC}{subtractIfCan} &
+\cross{OC}{zero?} &
+\cross{OC}{?*?} \\
+\cross{OC}{?**?} &
+\cross{OC}{?+?} &
+\cross{OC}{?-?} &
+\cross{OC}{-?} &
+\cross{OC}{?=?} \\
+\cross{OC}{?\^{}?} &
+\cross{OC}{?\~{}=?} &
+\cross{OC}{?$<$?} &
+\cross{OC}{?$<=$?} &
+\cross{OC}{?$>$?} \\
+\cross{OC}{?$>=$?} &
+\cross{OC}{?.?} &&&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{OC}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{OC}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{OC}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ imagi : % -> R
+ imagj : % -> R                       
+ imagk : % -> R
+ imagE : % -> R
+ imagI : % -> R                       
+ imagJ : % -> R
+ imagK : % -> R                       
+ octon : (R,R,R,R,R,R,R,R) -> %       
+ real : % -> R                        
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ abs : % -> R if R has RNS
+ characteristic : () -> NonNegativeInteger
+ coerce : R -> %                      
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ conjugate : % -> %
+ convert : % -> InputForm if R has KONVERT INFORM
+ inv : % -> % if R has FIELD          
+ map : ((R -> R),%) -> %              
+ norm : % -> R
+ rational : % -> Fraction Integer if R has INS
+ rational? : % -> Boolean if R has INS
+ rationalIfCan : % -> Union(Fraction Integer,"failed") if R has INS
+ retract : % -> R                     
+ retractIfCan : % -> Union(R,"failed")
+ zero? : % -> Boolean                 
+ ?<? : (%,%) -> Boolean if R has ORDSET
+ ?=? : (%,%) -> Boolean
+ ?+? : (%,%) -> %                     
+ -? : % -> %                          
+ ?*? : (R,%) -> %                     
+ ?*? : (Integer,%) -> %
+\end{verbatim}
+
+These exports come from \refto{Algebra}(R:CommutativeRing):
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ hash : % -> SingleInteger            
+ latex : % -> String
+ one? : % -> Boolean
+ recip : % -> Union(%,"failed")
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?^? : (%,NonNegativeInteger) -> %
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(R:CommutativeRing):
+\begin{verbatim}
+ coerce : Fraction Integer -> % if R has RETRACT FRAC INT
+ retract : % -> Fraction Integer if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
+\end{verbatim}
+
+These exports come from \refto{FullyEvalableOver}(R:CommutativeRing):
+\begin{verbatim}
+ eval : (%,Equation R) -> % if R has EVALAB R
+ eval : (%,List Symbol,List R) -> % if R has IEVALAB(SYMBOL,R)
+ eval : (%,List Equation R) -> % if R has EVALAB R
+ eval : (%,R,R) -> % if R has EVALAB R
+ eval : (%,List R,List R) -> % if R has EVALAB R
+ eval : (%,Symbol,R) -> % if R has IEVALAB(SYMBOL,R)
+ ?.? : (%,R) -> % if R has ELTAB(R,R)
+\end{verbatim}
+
+These exports come from \refto{Finite}():
+\begin{verbatim}
+ index : PositiveInteger -> % if R has FINITE
+ lookup : % -> PositiveInteger if R has FINITE
+ random : () -> % if R has FINITE
+ size : () -> NonNegativeInteger if R has FINITE
+\end{verbatim}
+
+These exports come from \refto{OrderedSet}():
+\begin{verbatim}
+ max : (%,%) -> % if R has ORDSET
+ min : (%,%) -> % if R has ORDSET
+ ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?>? : (%,%) -> Boolean if R has ORDSET
+ ?>=? : (%,%) -> Boolean if R has ORDSET
+\end{verbatim}
+
+These exports come from \refto{CharacteristicNonZero}():
+\begin{verbatim}
+ charthRoot : % -> Union(%,"failed") if R has CHARNZ
+\end{verbatim}
+
+<<category OC OctonionCategory>>=
+)abbrev category OC OctonionCategory
+++ Author: R. Wisbauer, J. Grabmeier
+++ Date Created: 05 September 1990
+++ Date Last Updated: 19 September 1990
+++ Basic Operations: _+, _*, octon, real, imagi, imagj, imagk,
+++  imagE, imagI, imagJ, imagK
+++ Related Constructors: QuaternionCategory
+++ Also See: 
+++ AMS Classifications:
+++ Keywords: octonion, non-associative algebra, Cayley-Dixon  
+++ References: e.g. I.L Kantor, A.S. Solodovnikov:
+++  Hypercomplex Numbers, Springer Verlag Heidelberg, 1989,
+++  ISBN 0-387-96980-2
+++ Description:
+++  OctonionCategory gives the categorial frame for the 
+++  octonions, and eight-dimensional non-associative algebra, 
+++  doubling the the quaternions in the same way as doubling
+++  the Complex numbers to get the quaternions.
+-- Examples: octonion.input
+ 
+OctonionCategory(R: CommutativeRing): Category ==
+  -- we are cheating a little bit, algebras in \Language{}
+  -- are mainly considered to be associative, but that's not 
+  -- an attribute and we can't guarantee that there is no piece
+  -- of code which implicitly
+  -- uses this. In a later version we shall properly combine
+  -- all this code in the context of general, non-associative
+  -- algebras, which are meanwhile implemented in \Language{}
+  Join(Algebra R, FullyRetractableTo R, FullyEvalableOver R) with
+     conjugate: % -> % 
+       ++ conjugate(o) negates the imaginary parts i,j,k,E,I,J,K of octonian o.
+     real:    % -> R 
+       ++ real(o) extracts real part of octonion o.
+     imagi:   % -> R      
+       ++ imagi(o) extracts the i part of octonion o.
+     imagj:   % -> R                
+       ++ imagj(o) extracts the j part of octonion o.
+     imagk:   % -> R 
+       ++ imagk(o) extracts the k part of octonion o.
+     imagE:   % -> R 
+       ++ imagE(o) extracts the imaginary E part of octonion o.
+     imagI:   % -> R              
+       ++ imagI(o) extracts the imaginary I part of octonion o.
+     imagJ:   % -> R      
+       ++ imagJ(o) extracts the imaginary J part of octonion o.
+     imagK:   % -> R
+       ++ imagK(o) extracts the imaginary K part of octonion o.
+     norm:    % -> R 
+       ++ norm(o) returns the norm of an octonion, equal to
+       ++ the sum of the squares
+       ++ of its coefficients.
+     octon: (R,R,R,R,R,R,R,R) -> %   
+       ++ octon(re,ri,rj,rk,rE,rI,rJ,rK) constructs an octonion 
+       ++ from scalars. 
+     if R has Finite then Finite
+     if R has OrderedSet then OrderedSet
+     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+     if R has CharacteristicZero then CharacteristicZero
+     if R has CharacteristicNonZero then CharacteristicNonZero
+     if R has RealNumberSystem then
+       abs:   % -> R 
+         ++ abs(o) computes the absolute value of an octonion, equal to 
+         ++ the square root of the \spadfunFrom{norm}{Octonion}.
+     if R has IntegerNumberSystem then
+       rational?    : % -> Boolean
+         ++ rational?(o) tests if o is rational, i.e. that all seven
+         ++ imaginary parts are 0.
+       rational     : % -> Fraction Integer
+         ++ rational(o) returns the real part if all seven 
+         ++ imaginary parts are 0.
+         ++ Error: if o is not rational.
+       rationalIfCan: % -> Union(Fraction Integer, "failed")
+         ++ rationalIfCan(o) returns the real part if
+         ++ all seven imaginary parts are 0, and "failed" otherwise.
+     if R has Field then
+       inv : % -> % 
+         ++ inv(o) returns the inverse of o if it exists.
+ add
+     characteristic() == 
+       characteristic()$R
+
+     conjugate x ==
+       octon(real x, - imagi x, - imagj x, - imagk x, - imagE x,_
+       - imagI x, - imagJ x, - imagK x)
+
+     map(fn, x)       ==
+       octon(fn real x,fn imagi x,fn imagj x,fn imagk x, fn imagE x,_
+       fn imagI x, fn imagJ x,fn imagK x)
+
+     norm x ==
+       real x * real x + imagi x * imagi x + _
+       imagj x * imagj x + imagk x * imagk x + _
+       imagE x * imagE x + imagI x * imagI x + _
+       imagJ x * imagJ x + imagK x * imagK x
+
+     x = y            ==
+       (real x = real y) and (imagi x = imagi y) and _
+       (imagj x = imagj y) and (imagk x = imagk y) and _
+       (imagE x = imagE y) and (imagI x = imagI y) and _
+       (imagJ x = imagJ y) and (imagK x = imagK y)
+
+     x + y            ==
+       octon(real x + real y, imagi x + imagi y,_
+       imagj x + imagj y, imagk x + imagk y,_
+       imagE x + imagE y, imagI x + imagI y,_
+       imagJ x + imagJ y, imagK x + imagK y)
+
+     - x              ==
+       octon(- real x, - imagi x, - imagj x, - imagk x,_
+       - imagE x, - imagI x, - imagJ x, - imagK x)
+
+     r:R * x:%        ==
+       octon(r * real x, r * imagi x, r * imagj x, r * imagk x,_
+       r * imagE x, r * imagI x, r * imagJ x, r * imagK x)
+
+     n:Integer * x:%  ==
+       octon(n * real x, n * imagi x, n * imagj x, n * imagk x,_
+       n * imagE x, n * imagI x, n * imagJ x, n * imagK x)
+
+     coerce(r:R)      ==
+       octon(r,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
+
+     coerce(n:Integer)      ==
+       octon(n :: R,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
+
+     zero? x ==
+       zero? real x and zero? imagi x and _
+       zero? imagj x and zero? imagk x and _
+       zero? imagE x and zero? imagI x and _
+       zero? imagJ x and zero? imagK x
+
+     retract(x):R ==
+       not (zero? imagi x and zero? imagj x and zero? imagk x and _
+       zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+         error "Cannot retract octonion."
+       real x
+
+     retractIfCan(x):Union(R,"failed") ==
+       not (zero? imagi x and zero? imagj x and zero? imagk x and _
+       zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+         "failed"
+       real x
+ 
+     coerce(x:%):OutputForm ==
+         part,z : OutputForm
+         y : %
+         zero? x => (0$R) :: OutputForm
+         not zero?(real x) =>
+           y := octon(0$R,imagi(x),imagj(x),imagk(x),imagE(x),
+             imagI(x),imagJ(x),imagK(x))
+           zero? y => real(x) :: OutputForm
+           (real(x) :: OutputForm) + (y :: OutputForm)
+         -- we know that the real part is 0
+         not zero?(imagi(x)) =>
+           y := octon(0$R,0$R,imagj(x),imagk(x),imagE(x),
+             imagI(x),imagJ(x),imagK(x))
+           z :=
+             part := "i"::Symbol::OutputForm
+--             one? imagi(x) => part
+             (imagi(x) = 1) => part
+             (imagi(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part and i part are 0
+         not zero?(imagj(x)) =>
+           y := octon(0$R,0$R,0$R,imagk(x),imagE(x),
+             imagI(x),imagJ(x),imagK(x))
+           z :=
+             part := "j"::Symbol::OutputForm
+--             one? imagj(x) => part
+             (imagj(x) = 1) => part
+             (imagj(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part and i and j parts are 0
+         not zero?(imagk(x)) =>
+           y := octon(0$R,0$R,0$R,0$R,imagE(x),
+             imagI(x),imagJ(x),imagK(x))
+           z :=
+             part := "k"::Symbol::OutputForm
+--             one? imagk(x) => part
+             (imagk(x) = 1) => part
+             (imagk(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part,i,j,k parts are 0
+         not zero?(imagE(x)) =>
+           y := octon(0$R,0$R,0$R,0$R,0$R,
+             imagI(x),imagJ(x),imagK(x))
+           z :=
+             part := "E"::Symbol::OutputForm
+--             one? imagE(x) => part
+             (imagE(x) = 1) => part
+             (imagE(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part,i,j,k,E parts are 0
+         not zero?(imagI(x)) =>
+           y := octon(0$R,0$R,0$R,0$R,0$R,0$R,imagJ(x),imagK(x))
+           z :=
+             part := "I"::Symbol::OutputForm
+--             one? imagI(x) => part
+             (imagI(x) = 1) => part
+             (imagI(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part,i,j,k,E,I parts are 0
+         not zero?(imagJ(x)) =>
+           y := octon(0$R,0$R,0$R,0$R,0$R,0$R,0$R,imagK(x))
+           z :=
+             part := "J"::Symbol::OutputForm
+--             one? imagJ(x) => part
+             (imagJ(x) = 1) => part
+             (imagJ(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part,i,j,k,E,I,J parts are 0
+         part := "K"::Symbol::OutputForm
+--         one? imagK(x) => part
+         (imagK(x) = 1) => part
+         (imagK(x) :: OutputForm) * part
+ 
+     if R has Field then
+       inv x ==
+         (norm x) = 0 => error "This octonion is not invertible."
+         (inv norm x) * conjugate x
+
+     if R has ConvertibleTo InputForm then
+       convert(x:%):InputForm ==
+         l : List InputForm := [convert("octon" :: Symbol),
+           convert(real x)$R, convert(imagi x)$R, convert(imagj x)$R,_
+             convert(imagk x)$R, convert(imagE x)$R,_
+             convert(imagI x)$R, convert(imagJ x)$R,_
+             convert(imagK x)$R]
+         convert(l)$InputForm
+
+     if R has OrderedSet then
+       x < y ==
+         real x = real y =>
+          imagi x = imagi y =>
+           imagj x = imagj y =>
+            imagk x = imagk y =>
+             imagE x = imagE y =>
+              imagI x = imagI y =>
+               imagJ x = imagJ y =>
+                imagK x < imagK y
+               imagJ x < imagJ y
+              imagI x < imagI y
+             imagE x < imagE y
+            imagk x < imagk y 
+           imagj x < imagj y 
+          imagi x < imagi y 
+         real x < real y
+ 
+     if R has RealNumberSystem then
+       abs x == sqrt norm x
+ 
+     if R has IntegerNumberSystem then
+       rational? x ==
+         (zero? imagi x) and (zero? imagj x) and (zero? imagk x) and _ 
+         (zero? imagE x) and (zero? imagI x) and (zero? imagJ x) and _
+         (zero? imagK x)
+
+       rational  x ==
+         rational? x => rational real x
+         error "Not a rational number"
+
+       rationalIfCan x ==
+         rational? x => rational real x
+         "failed"
+
+@
+<<OC.dotabb>>=
+"OC"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=OC"];
+"OC" -> "ALGEBRA"
+"OC" -> "FEVALAB"
+"OC" -> "FRETRCT"
+
+@
+<<OC.dotfull>>=
+"OctonionCategory(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=OC"];
+"OctonionCategory(a:CommutativeRing)" -> "Algebra(a:CommutativeRing)"
+"OctonionCategory(a:CommutativeRing)" -> "FullyEvalableOver(CommutativeRing)"
+"OctonionCategory(a:CommutativeRing)" ->
+   "FullyRetractableTo(a:CommutativeRing)"
+
+@
+<<OC.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"OctonionCategory(a:CommutativeRing)" [color=lightblue];
+"OctonionCategory(a:CommutativeRing)" -> "ALGEBRA..."
+"OctonionCategory(a:CommutativeRing)" -> "FEVALAB..."
+"OctonionCategory(a:CommutativeRing)" -> "FRETRCT..."
+
+"ALGEBRA..." [color=lightblue];
+"FEVALAB..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{QuaternionCategory}{QUATCAT}
+\pagepic{ps/v102quaternioncategory.ps}{QUATCAT}{0.70}
+
+{\bf See:}\\
+\pagefrom{Algebra}{ALGEBRA}
+\pagefrom{DifferentialExtension}{DIFEXT}
+\pagefrom{FullyEvalableOver}{FEVALAB}
+\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{QUATCAT}{0} &
+\cross{QUATCAT}{1} &
+\cross{QUATCAT}{abs} &
+\cross{QUATCAT}{characteristic} \\
+\cross{QUATCAT}{charthRoot} &
+\cross{QUATCAT}{coerce} &
+\cross{QUATCAT}{conjugate} &
+\cross{QUATCAT}{convert} \\
+\cross{QUATCAT}{D} &
+\cross{QUATCAT}{differentiate} &
+\cross{QUATCAT}{eval} &
+\cross{QUATCAT}{hash} \\
+\cross{QUATCAT}{imagI} &
+\cross{QUATCAT}{imagJ} &
+\cross{QUATCAT}{imagK} &
+\cross{QUATCAT}{inv} \\
+\cross{QUATCAT}{latex} &
+\cross{QUATCAT}{map} &
+\cross{QUATCAT}{max} &
+\cross{QUATCAT}{min} \\
+\cross{QUATCAT}{norm} &
+\cross{QUATCAT}{one?} &
+\cross{QUATCAT}{quatern} &
+\cross{QUATCAT}{rational} \\
+\cross{QUATCAT}{rational?} &
+\cross{QUATCAT}{rationalIfCan} &
+\cross{QUATCAT}{real} &
+\cross{QUATCAT}{recip} \\
+\cross{QUATCAT}{reducedSystem} &
+\cross{QUATCAT}{retract} &
+\cross{QUATCAT}{retractIfCan} &
+\cross{QUATCAT}{sample} \\
+\cross{QUATCAT}{subtractIfCan} &
+\cross{QUATCAT}{zero?} &
+\cross{QUATCAT}{?*?} &
+\cross{QUATCAT}{?**?} \\
+\cross{QUATCAT}{?+?} &
+\cross{QUATCAT}{?-?} &
+\cross{QUATCAT}{-?} &
+\cross{QUATCAT}{?=?} \\
+\cross{QUATCAT}{?\^{}?} &
+\cross{QUATCAT}{?\~{}=?} &
+\cross{QUATCAT}{?$<$?} &
+\cross{QUATCAT}{?$<=$?} \\
+\cross{QUATCAT}{?$>$?} &
+\cross{QUATCAT}{?$>=$?} &
+\cross{QUATCAT}{?.?} &
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item if \#1 has EntireRing then noZeroDivisors where
+{\bf \cross{QUATCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{QUATCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{QUATCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{QUATCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ imagI : % -> R
+ imagJ : % -> R                       
+ imagK : % -> R
+ quatern : (R,R,R,R) -> %
+ real : % -> R                        
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ abs : % -> R if R has RNS
+ characteristic : () -> NonNegativeInteger
+ coerce : R -> %                      
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ conjugate : % -> %
+ convert : % -> InputForm if R has KONVERT INFORM
+ differentiate : (%,(R -> R)) -> %
+ inv : % -> % if R has FIELD          
+ map : ((R -> R),%) -> %              
+ norm : % -> R
+ one? : % -> Boolean                  
+ rational : % -> Fraction Integer if R has INS
+ rational? : % -> Boolean if R has INS
+ rationalIfCan : % -> Union(Fraction Integer,"failed") if R has INS
+ retract : % -> R                     
+ retractIfCan : % -> Union(R,"failed")
+ zero? : % -> Boolean                 
+ ?=? : (%,%) -> Boolean
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?*? : (R,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?<? : (%,%) -> Boolean if R has ORDSET
+\end{verbatim}
+
+These exports come from \refto{Algebra}(R:CommutativeRing):
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ hash : % -> SingleInteger            
+ latex : % -> String
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?**? : (%,PositiveInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?^? : (%,NonNegativeInteger) -> %
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(R:CommutativeRing):
+\begin{verbatim}
+ coerce : Fraction Integer -> % if R has FIELD or R has RETRACT FRAC INT
+ retract : % -> Fraction Integer if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") 
+   if R has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
+\end{verbatim}
+
+These exports come from \refto{DifferentialExtension}(R:CommutativeRing):
+\begin{verbatim}
+ D : % -> % if R has DIFRING
+ D : (%,NonNegativeInteger) -> % if R has DIFRING
+ D : (%,(R -> R)) -> %                
+ D : (%,(R -> R),NonNegativeInteger) -> %
+ D : (%,Symbol) -> % if R has PDRING SYMBOL
+ D : (%,List Symbol) -> % if R has PDRING SYMBOL
+ D : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ D : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
+   if R has PDRING SYMBOL
+ differentiate : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,List Symbol) -> % if R has PDRING SYMBOL
+ differentiate : (%,NonNegativeInteger) -> % if R has DIFRING
+ differentiate : % -> % if R has DIFRING
+ differentiate : (%,(R -> R),NonNegativeInteger) -> %
+ differentiate : (%,Symbol) -> % if R has PDRING SYMBOL
+ ?*? : (%,%) -> %                     
+\end{verbatim}
+
+These exports come from \refto{FullyEvalableOver}(R:CommutativeRing):
+\begin{verbatim}
+ eval : (%,Equation R) -> % if R has EVALAB R
+ eval : (%,List Symbol,List R) -> % if R has IEVALAB(SYMBOL,R)
+ eval : (%,List Equation R) -> % if R has EVALAB R
+ eval : (%,R,R) -> % if R has EVALAB R
+ eval : (%,List R,List R) -> % if R has EVALAB R
+ eval : (%,Symbol,R) -> % if R has IEVALAB(SYMBOL,R)
+ ?.? : (%,R) -> % if R has ELTAB(R,R)
+\end{verbatim}
+
+These exports come from \refto{FullyLinearlyExplicitRingOver}(R)\\
+where R:CommutativeRing:
+\begin{verbatim}
+ recip : % -> Union(%,"failed")
+ reducedSystem : Matrix % -> Matrix Integer if R has LINEXP INT
+ reducedSystem :
+   (Matrix %,Vector %) ->
+      Record(mat: Matrix Integer,vec: Vector Integer) 
+        if R has LINEXP INT
+ reducedSystem : Matrix % -> Matrix R
+ reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix R,vec: Vector R)
+\end{verbatim}
+
+These exports come from \refto{OrderedSet}():
+\begin{verbatim}
+ max : (%,%) -> % if R has ORDSET
+ min : (%,%) -> % if R has ORDSET
+ ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?>? : (%,%) -> Boolean if R has ORDSET
+ ?>=? : (%,%) -> Boolean if R has ORDSET
+\end{verbatim}
+
+These exports come from \refto{DivisionRing}():
+\begin{verbatim}
+ ?**? : (%,Integer) -> % if R has FIELD
+ ?^? : (%,Integer) -> % if R has FIELD
+ ?*? : (Fraction Integer,%) -> % if R has FIELD
+ ?*? : (%,Fraction Integer) -> % if R has FIELD
+\end{verbatim}
+
+These exports come from \refto{CharacteristicNonZero}():
+\begin{verbatim}
+ charthRoot : % -> Union(%,"failed") if R has CHARNZ
+\end{verbatim}
+
+<<category QUATCAT QuaternionCategory>>=
+)abbrev category QUATCAT QuaternionCategory
+++ Author: Robert S. Sutor
+++ Date Created: 23 May 1990
+++ Change History:
+++   10 September 1990
+++ Basic Operations: (Algebra)
+++   abs, conjugate, imagI, imagJ, imagK, norm, quatern, rational,
+++   rational?, real
+++ Related Constructors: Quaternion, QuaternionCategoryFunctions2
+++ Also See: DivisionRing
+++ AMS Classifications: 11R52
+++ Keywords: quaternions, division ring, algebra
+++ Description:
+++   \spadtype{QuaternionCategory} describes the category of quaternions
+++   and implements functions that are not representation specific.
+ 
+QuaternionCategory(R: CommutativeRing): Category ==
+  Join(Algebra R, FullyRetractableTo R, DifferentialExtension R,
+   FullyEvalableOver R, FullyLinearlyExplicitRingOver R) with
+ 
+     conjugate: $ -> $
+       ++ conjugate(q) negates the imaginary parts of quaternion \spad{q}.
+     imagI:   $ -> R
+       ++ imagI(q) extracts the imaginary i part of quaternion \spad{q}.
+     imagJ:   $ -> R
+       ++ imagJ(q) extracts the imaginary j part of quaternion \spad{q}.
+     imagK:   $ -> R
+       ++ imagK(q) extracts the imaginary k part of quaternion \spad{q}.
+     norm:    $ -> R
+       ++ norm(q) computes the norm of \spad{q} (the sum of the
+       ++ squares of the components).
+     quatern: (R,R,R,R) -> $
+       ++ quatern(r,i,j,k) constructs a quaternion from scalars.
+     real:    $ -> R
+       ++ real(q) extracts the real part of quaternion \spad{q}.
+ 
+     if R has EntireRing then EntireRing
+     if R has OrderedSet then OrderedSet
+     if R has Field then DivisionRing
+     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+     if R has CharacteristicZero then CharacteristicZero
+     if R has CharacteristicNonZero then CharacteristicNonZero
+     if R has RealNumberSystem then
+       abs    : $ -> R
+         ++ abs(q) computes the absolute value of quaternion \spad{q}
+         ++ (sqrt of norm).
+     if R has IntegerNumberSystem then
+       rational?    : $ -> Boolean
+         ++ rational?(q) returns {\it true} if all the imaginary
+         ++ parts of \spad{q} are zero and the real part can be
+         ++ converted into a rational number, and {\it false}
+         ++ otherwise.
+       rational     : $ -> Fraction Integer
+         ++ rational(q) tries to convert \spad{q} into a
+         ++ rational number. Error: if this is not
+         ++ possible. If \spad{rational?(q)} is true, the
+         ++ conversion will be done and the rational number returned.
+       rationalIfCan: $ -> Union(Fraction Integer, "failed")
+         ++ rationalIfCan(q) returns \spad{q} as a rational number,
+         ++ or "failed" if this is not possible.
+         ++ Note: if \spad{rational?(q)} is true, the conversion
+         ++ can be done and the rational number will be returned.
+ 
+ add
+ 
+       characteristic() ==
+         characteristic()$R
+
+       conjugate x      ==
+         quatern(real x, - imagI x, - imagJ x, - imagK x)
+
+       map(fn, x)       ==
+         quatern(fn real x, fn imagI x, fn imagJ x, fn imagK x)
+
+       norm x ==
+         real x * real x + imagI x * imagI x +
+           imagJ x * imagJ x + imagK x * imagK x
+
+       x = y            ==
+         (real x = real y) and (imagI x = imagI y) and
+           (imagJ x = imagJ y) and (imagK x = imagK y)
+
+       x + y            ==
+         quatern(real x + real y, imagI x + imagI y,
+           imagJ x + imagJ y, imagK x + imagK y)
+
+       x - y            ==
+         quatern(real x - real y, imagI x - imagI y,
+           imagJ x - imagJ y, imagK x - imagK y)
+
+       - x              ==
+         quatern(- real x, - imagI x, - imagJ x, - imagK x)
+
+       r:R * x:$        ==
+         quatern(r * real x, r * imagI x, r * imagJ x, r * imagK x)
+
+       n:Integer * x:$  ==
+         quatern(n * real x, n * imagI x, n * imagJ x, n * imagK x)
+
+       differentiate(x:$, d:R -> R) ==
+         quatern(d real x, d imagI x, d imagJ x, d imagK x)
+
+       coerce(r:R)      ==
+         quatern(r,0$R,0$R,0$R)
+
+       coerce(n:Integer)      ==
+         quatern(n :: R,0$R,0$R,0$R)
+
+       one? x ==
+--         one? real x and zero? imagI x and
+         (real x) = 1 and zero? imagI x and
+           zero? imagJ x and zero? imagK x
+
+       zero? x ==
+         zero? real x and zero? imagI x and
+           zero? imagJ x and zero? imagK x
+
+       retract(x):R ==
+         not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
+           error "Cannot retract quaternion."
+         real x
+
+       retractIfCan(x):Union(R,"failed") ==
+         not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
+           "failed"
+         real x
+ 
+       coerce(x:$):OutputForm ==
+         part,z : OutputForm
+         y : $
+         zero? x => (0$R) :: OutputForm
+         not zero?(real x) =>
+           y := quatern(0$R,imagI(x),imagJ(x),imagK(x))
+           zero? y => real(x) :: OutputForm
+           (real(x) :: OutputForm) + (y :: OutputForm)
+         -- we know that the real part is 0
+         not zero?(imagI(x)) =>
+           y := quatern(0$R,0$R,imagJ(x),imagK(x))
+           z :=
+             part := "i"::Symbol::OutputForm
+--             one? imagI(x) => part
+             (imagI(x) = 1) => part
+             (imagI(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part and i part are 0
+         not zero?(imagJ(x)) =>
+           y := quatern(0$R,0$R,0$R,imagK(x))
+           z :=
+             part := "j"::Symbol::OutputForm
+--             one? imagJ(x) => part
+             (imagJ(x) = 1) => part
+             (imagJ(x) :: OutputForm) * part
+           zero? y => z
+           z + (y :: OutputForm)
+         -- we know that the real part and i and j parts are 0
+         part := "k"::Symbol::OutputForm
+--         one? imagK(x) => part
+         (imagK(x) = 1) => part
+         (imagK(x) :: OutputForm) * part
+ 
+       if R has Field then
+         inv x ==
+           norm x = 0 => error "This quaternion is not invertible."
+           (inv norm x) * conjugate x
+ 
+       if R has ConvertibleTo InputForm then
+         convert(x:$):InputForm ==
+           l : List InputForm := [convert("quatern" :: Symbol),
+             convert(real x)$R, convert(imagI x)$R, convert(imagJ x)$R,
+               convert(imagK x)$R]
+           convert(l)$InputForm
+ 
+       if R has OrderedSet then
+         x < y ==
+           real x = real y =>
+             imagI x = imagI y =>
+               imagJ x = imagJ y =>
+                 imagK x < imagK y
+               imagJ x < imagJ y
+             imagI x < imagI y
+           real x < real y
+ 
+       if R has RealNumberSystem then
+         abs x == sqrt norm x
+ 
+       if R has IntegerNumberSystem then
+         rational? x ==
+           (zero? imagI x) and (zero? imagJ x) and (zero? imagK x)
+
+         rational  x ==
+           rational? x => rational real x
+           error "Not a rational number"
+
+         rationalIfCan x ==
+           rational? x => rational real x
+           "failed"
+
+@
+<<QUATCAT.dotabb>>=
+"QUATCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=QUATCAT"];
+"QUATCAT" -> "ALGEBRA"
+"QUATCAT" -> "DIFEXT"
+"QUATCAT" -> "FEVALAB"
+"QUATCAT" -> "FLINEXP"
+"QUATCAT" -> "FRETRCT"
+
+@
+<<QUATCAT.dotfull>>=
+"QuaternionCategory(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=QUATCAT"];
+"QuaternionCategory(a:CommutativeRing)" ->
+   "Algebra(a:CommutativeRing)"
+"QuaternionCategory(a:CommutativeRing)" ->
+   "DifferentialExtension(CommutativeRing)"
+"QuaternionCategory(a:CommutativeRing)" ->
+   "FullyEvalableOver(CommutativeRing)"
+"QuaternionCategory(a:CommutativeRing)" ->
+   "FullyLinearlyExplicitRingOver(a:CommutativeRing)"
+"QuaternionCategory(a:CommutativeRing)" ->
+   "FullyRetractableTo(a:CommutativeRing)"
+
+@
+<<QUATCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"QuaternionCategory(a:CommutativeRing)" [color=lightblue];
+"QuaternionCategory(a:CommutativeRing)" -> "ALGEBRA..."
+"QuaternionCategory(a:CommutativeRing)" -> "DIFEXT..."
+"QuaternionCategory(a:CommutativeRing)" -> "FEVALAB..."
+"QuaternionCategory(a:CommutativeRing)" -> "FLINEXP..."
+"QuaternionCategory(a:CommutativeRing)" -> "FRETRCT..."
+
+"ALGEBRA..." [color=lightblue];
+"DIFEXT..." [color=lightblue];
+"FEVALAB..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{SquareMatrixCategory}{SMATCAT}
+\pagepic{ps/v102squarematrixcategory.ps}{SMATCAT}{0.25}
+
+{\bf See:}\\
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{DifferentialExtension}{DIFEXT}
+\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{RectangularMatrixCategory}{RMATCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lll}
+\cross{SMATCAT}{0} &
+\cross{SMATCAT}{1} &
+\cross{SMATCAT}{antisymmetric?} \\
+\cross{SMATCAT}{any?} &
+\cross{SMATCAT}{characteristic} &
+\cross{SMATCAT}{coerce} \\
+\cross{SMATCAT}{column} &
+\cross{SMATCAT}{copy} &
+\cross{SMATCAT}{count} \\
+\cross{SMATCAT}{D} &
+\cross{SMATCAT}{determinant} &
+\cross{SMATCAT}{differentiate} \\
+\cross{SMATCAT}{diagonal} &
+\cross{SMATCAT}{diagonal?} &
+\cross{SMATCAT}{diagonalMatrix} \\
+\cross{SMATCAT}{diagonalProduct} &
+\cross{SMATCAT}{elt} &
+\cross{SMATCAT}{empty} \\
+\cross{SMATCAT}{empty?} &
+\cross{SMATCAT}{eq?} &
+\cross{SMATCAT}{eval} \\
+\cross{SMATCAT}{every?} &
+\cross{SMATCAT}{exquo} &
+\cross{SMATCAT}{hash} \\
+\cross{SMATCAT}{inverse} &
+\cross{SMATCAT}{latex} &
+\cross{SMATCAT}{less?} \\
+\cross{SMATCAT}{listOfLists} &
+\cross{SMATCAT}{map} &
+\cross{SMATCAT}{map!} \\
+\cross{SMATCAT}{matrix} &
+\cross{SMATCAT}{maxColIndex} &
+\cross{SMATCAT}{maxRowIndex} \\
+\cross{SMATCAT}{member?} &
+\cross{SMATCAT}{members} &
+\cross{SMATCAT}{minColIndex} \\
+\cross{SMATCAT}{minordet} &
+\cross{SMATCAT}{minRowIndex} &
+\cross{SMATCAT}{more?} \\
+\cross{SMATCAT}{ncols} &
+\cross{SMATCAT}{nrows} &
+\cross{SMATCAT}{nullSpace} \\
+\cross{SMATCAT}{nullity} &
+\cross{SMATCAT}{one?} &
+\cross{SMATCAT}{parts} \\
+\cross{SMATCAT}{qelt} &
+\cross{SMATCAT}{rank} &
+\cross{SMATCAT}{recip} \\
+\cross{SMATCAT}{reducedSystem} &
+\cross{SMATCAT}{retract} &
+\cross{SMATCAT}{retractIfCan} \\
+\cross{SMATCAT}{row} &
+\cross{SMATCAT}{rowEchelon} &
+\cross{SMATCAT}{sample} \\
+\cross{SMATCAT}{scalarMatrix} &
+\cross{SMATCAT}{size?} &
+\cross{SMATCAT}{square?} \\
+\cross{SMATCAT}{subtractIfCan} &
+\cross{SMATCAT}{symmetric?} &
+\cross{SMATCAT}{trace} \\
+\cross{SMATCAT}{zero?} &
+\cross{SMATCAT}{\#?} &
+\cross{SMATCAT}{?\^{}?} \\
+\cross{SMATCAT}{?*?} &
+\cross{SMATCAT}{?**?} &
+\cross{SMATCAT}{?+?} \\
+\cross{SMATCAT}{?-?} &
+\cross{SMATCAT}{-?} &
+\cross{SMATCAT}{?=?} \\
+\cross{SMATCAT}{?\~{}=?} &
+\cross{SMATCAT}{?/?} &
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{SMATCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{SMATCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{SMATCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item {\bf \cross{SMATCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf nil}
+\end{itemize}
+
+TPDHERE: How did MATCAT get in the type tower?
+\begin{verbatim}
+ determinant : % -> R if R has commutative *
+ inverse : % -> Union(%,"failed") if R has FIELD
+\end{verbatim}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ diagonalMatrix : List R -> %
+ minordet : % -> R if R has commutative *
+ scalarMatrix : R -> %                
+ ?*? : (Row,%) -> Row                 
+ ?*? : (%,Col) -> Col
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ coerce : R -> %                      
+ diagonal : % -> Row
+ diagonalProduct : % -> R             
+ differentiate : (%,(R -> R)) -> %
+ reducedSystem : Matrix % -> Matrix R
+ reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix R,vec: Vector R)
+ retract : % -> R
+ retractIfCan : % -> Union(R,"failed")
+ trace : % -> R
+ ?**? : (%,Integer) -> % if R has FIELD
+ ?**? : (%,NonNegativeInteger) -> %
+\end{verbatim}
+
+These exports come from \refto{DifferentialExtension}(R:Ring):
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ characteristic : () -> NonNegativeInteger
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ D : % -> % if R has DIFRING          
+ D : (%,NonNegativeInteger) -> % if R has DIFRING
+ D : (%,(R -> R)) -> %
+ D : (%,(R -> R),NonNegativeInteger) -> %
+ D : (%,Symbol) -> % if R has PDRING SYMBOL
+ D : (%,List Symbol) -> % if R has PDRING SYMBOL
+ D : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ D : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,List Symbol) -> % if R has PDRING SYMBOL
+ differentiate : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,NonNegativeInteger) -> % if R has DIFRING
+ differentiate : % -> % if R has DIFRING
+ differentiate : (%,(R -> R),NonNegativeInteger) -> %
+ differentiate : (%,Symbol) -> % if R has PDRING SYMBOL
+ hash : % -> SingleInteger            
+ latex : % -> String
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")       
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (%,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (NonNegativeInteger,%) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+These exports come from \refto{BiModule}(R:Ring,R:Ring):
+\begin{verbatim}
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from\\
+\refto{RectangularMatrixCategory}(ndim,ndim,R,Row,Col)\\
+where ndim:NonNegativeInteger, R:Ring, Row:DirectProductCategory(ndim,R)\\
+Col:DirectProductCategory(ndim,R):
+\begin{verbatim}
+ antisymmetric? : % -> Boolean
+ any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ column : (%,Integer) -> Col
+ copy : % -> %                        
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ diagonal? : % -> Boolean             
+ elt : (%,Integer,Integer) -> R
+ elt : (%,Integer,Integer,R) -> R     
+ empty : () -> %
+ empty? : % -> Boolean                
+ eq? : (%,%) -> Boolean
+ eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ less? : (%,NonNegativeInteger) -> Boolean
+ listOfLists : % -> List List R       
+ map : ((R -> R),%) -> %
+ map : (((R,R) -> R),%,%) -> %        
+ map! : ((R -> R),%) -> % if $ has shallowlyMutable
+ matrix : List List R -> %
+ maxColIndex : % -> Integer           
+ maxRowIndex : % -> Integer
+ minColIndex : % -> Integer           
+ minRowIndex : % -> Integer
+ members : % -> List R if $ has finiteAggregate
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ more? : (%,NonNegativeInteger) -> Boolean
+ ncols : % -> NonNegativeInteger      
+ nrows : % -> NonNegativeInteger
+ nullity : % -> NonNegativeInteger if R has INTDOM
+ nullSpace : % -> List Col if R has INTDOM
+ parts : % -> List R if $ has finiteAggregate
+ qelt : (%,Integer,Integer) -> R
+ rank : % -> NonNegativeInteger if R has INTDOM
+ row : (%,Integer) -> Row             
+ rowEchelon : % -> % if R has EUCDOM
+ size? : (%,NonNegativeInteger) -> Boolean
+ square? : % -> Boolean
+ symmetric? : % -> Boolean            
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?/? : (%,R) -> % if R has FIELD
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(R:Ring):
+\begin{verbatim}
+ coerce : Fraction Integer -> % if R has RETRACT FRAC INT
+ retract : % -> Fraction Integer if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
+\end{verbatim}
+
+These exports come from \refto{FullyLinearlyExplicitRingOver}(R:Ring):
+\begin{verbatim}
+ reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix Integer,vec: Vector Integer) if R has LINEXP INT
+ reducedSystem : Matrix % -> Matrix Integer if R has LINEXP INT
+\end{verbatim}
+
+<<category SMATCAT SquareMatrixCategory>>=
+)abbrev category SMATCAT SquareMatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: SquareMatrix(ndim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{SquareMatrixCategory} is a general square matrix category which
+++   allows different representations and indexing schemes.  Rows and
+++   columns may be extracted with rows returned as objects of
+++   type Row and colums returned as objects of type Col.
+SquareMatrixCategory(ndim,R,Row,Col): Category == Definition where
+  ndim : NonNegativeInteger
+  R    : Ring
+  Row  : DirectProductCategory(ndim,R)
+  Col  : DirectProductCategory(ndim,R)
+  I ==> Integer
+
+  Definition ==> Join(DifferentialExtension R, BiModule(R, R),_
+                      RectangularMatrixCategory(ndim,ndim,R,Row,Col),_
+                      FullyRetractableTo R,_
+                      FullyLinearlyExplicitRingOver R) with
+    if R has CommutativeRing then Module(R)
+    scalarMatrix: R -> %
+      ++ \spad{scalarMatrix(r)} returns an n-by-n matrix with r's on the
+      ++ diagonal and zeroes elsewhere.
+    diagonalMatrix: List R -> %
+      ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
+      ++ of l on the diagonal.
+    diagonal: % -> Row
+      ++ \spad{diagonal(m)} returns a row consisting of the elements on the
+      ++ diagonal of the matrix m.
+    trace: % -> R
+      ++ \spad{trace(m)} returns the trace of the matrix m. this is the sum
+      ++ of the elements on the diagonal of the matrix m.
+    diagonalProduct: % -> R
+      ++ \spad{diagonalProduct(m)} returns the product of the elements on the
+      ++ diagonal of the matrix m.
+    "*": (%,Col) -> Col
+      ++ \spad{x * c} is the product of the matrix x and the column vector c.
+      ++ Error: if the dimensions are incompatible.
+    "*": (Row,%) -> Row
+      ++ \spad{r * x} is the product of the row vector r and the matrix x.
+      ++ Error: if the dimensions are incompatible.
+
+--% Linear algebra
+
+    if R has commutative("*") then
+      Algebra R
+      determinant: % -> R
+        ++ \spad{determinant(m)} returns the determinant of the matrix m.
+      minordet: % -> R
+        ++ \spad{minordet(m)} computes the determinant of the matrix m
+        ++ using minors.
+    if R has Field then
+      inverse: % -> Union(%,"failed")
+        ++ \spad{inverse(m)} returns the inverse of the matrix m, if that
+        ++ matrix is invertible and returns "failed" otherwise.
+      "**": (%,Integer) -> %
+        ++ \spad{m**n} computes an integral power of the matrix m.
+        ++ Error: if the matrix is not invertible.
+
+   add
+    minr ==> minRowIndex
+    maxr ==> maxRowIndex
+    minc ==> minColIndex
+    maxc ==> maxColIndex
+    mini ==> minIndex
+    maxi ==> maxIndex
+
+    positivePower:(%,Integer) -> %
+    positivePower(x,n) ==
+--      one? n => x
+      (n = 1) => x
+      odd? n => x * positivePower(x,n - 1)
+      y := positivePower(x,n quo 2)
+      y * y
+
+    x:% ** n:NonNegativeInteger ==
+      zero? n => scalarMatrix 1
+      positivePower(x,n)
+
+    coerce(r:R) == scalarMatrix r
+
+    equation2R: Vector % -> Matrix R
+
+    differentiate(x:%,d:R -> R) == map(d,x)
+
+    diagonal x ==
+      v:Vector(R) := new(ndim,0)
+      for i in minr x .. maxr x
+        for j in minc x .. maxc x
+          for k in minIndex v .. maxIndex v repeat
+            qsetelt_!(v, k, qelt(x, i, j))
+      directProduct v
+
+    retract(x:%):R ==
+      diagonal? x => retract diagonal x
+      error "Not retractable"
+
+    retractIfCan(x:%):Union(R, "failed") ==
+      diagonal? x => retractIfCan diagonal x
+      "failed"
+
+    equation2R v ==
+      ans:Matrix(Col) := new(ndim,#v,0)
+      for i in minr ans .. maxr ans repeat
+        for j in minc ans .. maxc ans repeat
+          qsetelt_!(ans, i, j, column(qelt(v, j), i))
+      reducedSystem ans
+
+    reducedSystem(x:Matrix %):Matrix(R) ==
+      empty? x => new(0,0,0)
+      reduce(vertConcat, [equation2R row(x, i)
+                               for i in minr x .. maxr x])$List(Matrix R)
+
+    reducedSystem(m:Matrix %, v:Vector %):
+     Record(mat:Matrix R, vec:Vector R) ==
+      vh:Vector(R) :=
+        empty? v => new(0,0)
+        rh := reducedSystem(v::Matrix %)@Matrix(R)
+        column(rh, minColIndex rh)
+      [reducedSystem(m)@Matrix(R), vh]
+
+    trace x ==
+      tr : R := 0
+      for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
+        tr := tr + x(i,j)
+      tr
+
+    diagonalProduct x ==
+      pr : R := 1
+      for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
+        pr := pr * x(i,j)
+      pr
+
+    if R has Field then
+
+      x:% ** n:Integer ==
+        zero? n => scalarMatrix 1
+        positive? n => positivePower(x,n)
+        (xInv := inverse x) case "failed" =>
+          error "**: matrix must be invertible"
+        positivePower(xInv :: %,-n)
+
+@
+<<SMATCAT.dotabb>>=
+"SMATCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=SMATCAT"];
+"SMATCAT" -> "BMODULE"
+"SMATCAT" -> "DIFEXT"
+"SMATCAT" -> "FLINEXP"
+"SMATCAT" -> "FRETRCT"
+"SMATCAT" -> "RMATCAT"
+
+@
+<<SMATCAT.dotfull>>=
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=SMATCAT"];
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "BiModule(a:Ring,b:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "DifferentialExtension(a:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "FullyLinearlyExplicitRingOver(a:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "FullyRetractableTo(a:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+
+@
+<<SMATCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ [color=lightblue];
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "BiModule(a:Ring,b:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "DifferentialExtension(a:Ring)"
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "FLINEXP..."
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "FRETRCT..."
+"SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)"
+ -> "RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+
+"DifferentialExtension(a:Ring)" [color=lightblue];
+"DifferentialExtension(a:Ring)" -> "Ring()"
+"DifferentialExtension(a:Ring)" -> "DifferentialRing()"
+"DifferentialExtension(a:Ring)" -> "PartialDifferentialRing(Symbol)"
+
+"PartialDifferentialRing(Symbol)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=PDRING"];
+"PartialDifferentialRing(Symbol)" ->
+    "PartialDifferentialRing(a:SetCategory)"
+
+"PartialDifferentialRing(a:SetCategory)" [color=lightblue];
+"PartialDifferentialRing(a:SetCategory)" -> "Ring()"
+
+"DifferentialRing()" [color=lightblue];
+"DifferentialRing()" -> "Ring()"
+
+"Ring()" [color=lightblue];
+"Ring()" -> "Rng()"
+"Ring()" -> "Monoid()"
+"Ring()" -> "LeftModule(a:Ring)"
+
+"Rng()" [color=lightblue];
+"Rng()" -> "ABELGRP..."
+"Rng()" -> "SGROUP..."
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SGROUP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LMODULE..."
+
+"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+ [color=lightblue];
+"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+  -> "BiModule(a:Ring,b:Ring)"
+"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+  -> "HOAGG..."
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"FRETRCT..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+"SGROUP..." [color=lightblue];
+"LMODULE..." [color=lightblue];
+"HOAGG..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{XPolynomialsCat}{XPOLYC}
+\pagepic{ps/v102xpolynomialscat.ps}{XPOLYC}{0.50}
+
+{\bf See:}\\
+\pagefrom{XFreeAlgebra}{XFALG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{XPOLYC}{0} &
+\cross{XPOLYC}{1} &
+\cross{XPOLYC}{characteristic} &
+\cross{XPOLYC}{coef} &
+\cross{XPOLYC}{coerce} \\
+\cross{XPOLYC}{constant} &
+\cross{XPOLYC}{constant?} &
+\cross{XPOLYC}{degree} &
+\cross{XPOLYC}{hash} &
+\cross{XPOLYC}{latex} \\
+\cross{XPOLYC}{lquo} &
+\cross{XPOLYC}{map} &
+\cross{XPOLYC}{maxdeg} &
+\cross{XPOLYC}{mindeg} &
+\cross{XPOLYC}{mindegTerm} \\
+\cross{XPOLYC}{mirror} &
+\cross{XPOLYC}{monom} &
+\cross{XPOLYC}{monomial?} &
+\cross{XPOLYC}{one?} &
+\cross{XPOLYC}{quasiRegular} \\
+\cross{XPOLYC}{quasiRegular?} &
+\cross{XPOLYC}{recip} &
+\cross{XPOLYC}{retract} &
+\cross{XPOLYC}{retractIfCan} &
+\cross{XPOLYC}{rquo} \\
+\cross{XPOLYC}{sample} &
+\cross{XPOLYC}{sh} &
+\cross{XPOLYC}{subtractIfCan} &
+\cross{XPOLYC}{trunc} &
+\cross{XPOLYC}{varList} \\
+\cross{XPOLYC}{zero?} &
+\cross{XPOLYC}{?*?} &
+\cross{XPOLYC}{?**?} &
+\cross{XPOLYC}{?+?} &
+\cross{XPOLYC}{?-?} \\
+\cross{XPOLYC}{-?} &
+\cross{XPOLYC}{?=?} &
+\cross{XPOLYC}{?\^{}?} &
+\cross{XPOLYC}{?\~{}=?} &
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item if Ring has noZeroDivisors then noZeroDivisors where
+{\bf \cross{XPOLYC}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{XPOLYC}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{XPOLYC}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{XPOLYC}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ degree : % -> NonNegativeInteger
+ maxdeg : % -> OrderedFreeMonoid vl
+ trunc : (%,NonNegativeInteger) -> %
+\end{verbatim}
+
+These exports come from \refto{Aggregate}():
+\begin{verbatim}
+\end{verbatim}
+
+These exports come from \refto{XFreeAlgebra}(vl:OrderedSet,R:Ring):
+\begin{verbatim}
+ 0 : () -> %                          
+ 1 : () -> %
+ characteristic : () -> NonNegativeInteger
+ coef : (%,OrderedFreeMonoid vl) -> R
+ coef : (%,%) -> R                    
+ coerce : % -> OutputForm             
+ coerce : R -> %                      
+ coerce : OrderedFreeMonoid vl -> %
+ coerce : Integer -> %
+ coerce : vl -> %
+ constant : % -> R
+ constant? : % -> Boolean             
+ hash : % -> SingleInteger            
+ latex : % -> String
+ lquo : (%,OrderedFreeMonoid vl) -> %
+ lquo : (%,%) -> %                    
+ lquo : (%,vl) -> %
+ map : ((R -> R),%) -> %              
+ mindeg : % -> OrderedFreeMonoid vl
+ mindegTerm : % -> Record(k: OrderedFreeMonoid vl,c: R)
+ mirror : % -> %
+ monom : (OrderedFreeMonoid vl,R) -> %
+ monomial? : % -> Boolean             
+ one? : % -> Boolean
+ quasiRegular : % -> %                
+ quasiRegular? : % -> Boolean
+ recip : % -> Union(%,"failed")       
+ retract : % -> OrderedFreeMonoid vl
+ retractIfCan : % -> Union(OrderedFreeMonoid vl,"failed")
+ rquo : (%,OrderedFreeMonoid vl) -> %
+ rquo : (%,%) -> %
+ rquo : (%,vl) -> %                   
+ sample : () -> %
+ sh : (%,NonNegativeInteger) -> % if R has COMRING
+ sh : (%,%) -> % if R has COMRING
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ varList : % -> List vl               
+ zero? : % -> Boolean
+ ?+? : (%,%) -> %
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %
+ ?*? : (Integer,%) -> %               
+ ?*? : (%,%) -> %
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+ ?-? : (%,%) -> %                     
+ -? : % -> %
+ ?**? : (%,PositiveInteger) -> %      
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %
+ ?*? : (vl,%) -> %                    
+\end{verbatim}
+
+These exports come from \refto{SetCategory}():
+\begin{verbatim}
+\end{verbatim}
+
+<<category XPOLYC XPolynomialsCat>>=
+)abbrev category XPOLYC XPolynomialsCat
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++   The Category of polynomial rings with non-commutative variables.
+++   The coefficient ring may be non-commutative too. 
+++   However coefficients commute with vaiables.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XPolynomialsCat(vl:OrderedSet,R:Ring):Category == Export where
+  WORD ==> OrderedFreeMonoid(vl)
+
+  Export == XFreeAlgebra(vl,R) with
+    maxdeg: % -> WORD 
+      ++ \spad{maxdeg(p)} returns the greatest leading word in the 
+      ++ support of \spad{p}.
+    degree: % -> NonNegativeInteger 
+      ++ \spad{degree(p)} returns the degree of \spad{p}. 
+      ++  Note that the degree of a word is its length. 
+    trunc : (% , NonNegativeInteger) -> %
+      ++  \spad{trunc(p,n)} returns the polynomial \spad{p} truncated 
+      ++ at order \spad{n}.
+
+@
+<<XPOLYC.dotabb>>=
+"XPOLYC"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
+"XPOLYC" -> "XFALG"
+
+@
+<<XPOLYC.dotfull>>=
+"XPolynomialsCat(a:OrderedRing,b:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
+"XPolynomialsCat(a:OrderedRing,b:Ring)" -> 
+   "XFreeAlgebra(a:OrderedSet,b:Ring)"
+
+@
+<<XPOLYC.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"XPolynomialsCat(a:OrderedRing,b:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=XPOLYC"];
+"XPolynomialsCat(a:OrderedRing,b:Ring)" -> 
+   "XFreeAlgebra(a:OrderedSet,b:Ring)"
+
+"XFreeAlgebra(a:OrderedSet,b:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=XFALG"];
+"XFreeAlgebra(a:OrderedSet,b:Ring)" -> "Ring()"
+"XFreeAlgebra(a:OrderedSet,b:Ring)" -> "XAlgebra(a:Ring)"
+"XFreeAlgebra(a:OrderedSet,b:Ring)" -> 
+    "RetractableTo(OrderedFreeMonoid(OrderedSet))"
+
+"RetractableTo(OrderedFreeMonoid(OrderedSet))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
+"RetractableTo(OrderedFreeMonoid(OrderedSet))" -> "RetractableTo(a:Type)"
+
+"XAlgebra(a:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=XALG"];
+"XAlgebra(a:Ring)" -> "Ring()"
+"XAlgebra(a:Ring)" -> "BiModule(a:Ring,b:Ring)"
+
+"Ring()" [color=lightblue];
+"Ring()" -> "Rng()"
+"Ring()" -> "Monoid()"
+"Ring()" -> "LeftModule(a:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"Rng()" [color=lightblue];
+"Rng()" -> "ABELGRP..."
+"Rng()" -> "SemiGroup()"
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SemiGroup()"
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"SemiGroup()" [color=lightblue];
+"SemiGroup()" -> "SETCAT..."
+"SemiGroup()" -> "REPSQ..."
+
+"RetractableTo(a:Type)" [color=lightblue];
+"RetractableTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+}
+
+@
+\chapter{Category Layer 12}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{AbelianMonoidRing}{AMR}
+\pagepic{ps/v102abelianmonoidring.ps}{AMR}{0.65}
+
+{\bf See:}\\
+\pageto{FiniteAbelianMonoidRing}{FAMR}
+\pageto{PowerSeriesCategory}{PSCAT}
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{Ring}{RING}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{AMR}{0} &
+\cross{AMR}{1} &
+\cross{AMR}{associates?} &
+\cross{AMR}{characteristic} \\
+\cross{AMR}{charthRoot} &
+\cross{AMR}{coefficient} &
+\cross{AMR}{coerce} &
+\cross{AMR}{degree} \\
+\cross{AMR}{exquo} &
+\cross{AMR}{hash} &
+\cross{AMR}{latex} &
+\cross{AMR}{leadingCoefficient} \\
+\cross{AMR}{leadingMonomial} &
+\cross{AMR}{map} &
+\cross{AMR}{monomial} &
+\cross{AMR}{monomial?} \\
+\cross{AMR}{one?} &
+\cross{AMR}{recip} &
+\cross{AMR}{reductum} &
+\cross{AMR}{sample} \\
+\cross{AMR}{subtractIfCan} &
+\cross{AMR}{unit?} &
+\cross{AMR}{unitCanonical} &
+\cross{AMR}{unitNormal} \\
+\cross{AMR}{zero?} &
+\cross{AMR}{?*?} &
+\cross{AMR}{?**?} &
+\cross{AMR}{?+?} \\
+\cross{AMR}{?-?} &
+\cross{AMR}{-?} &
+\cross{AMR}{?=?} &
+\cross{AMR}{?\^{}?} \\
+\cross{AMR}{?\~{}=?} &
+\cross{AMR}{?/?} &&
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item if \$ has CommutativeRing then commutative(``*'') where
+{\bf \cross{AMR}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\item if \$ has IntegralDomain then noZeroDivisors where
+{\bf \cross{AMR}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{AMR}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{AMR}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{AMR}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ coefficient : (%,E) -> R
+ degree : % -> E                      
+ leadingCoefficient : % -> R
+ leadingMonomial : % -> %             
+ monomial : (R,E) -> %                
+ reductum : % -> %                    
+ ?/? : (%,R) -> % if R has FIELD
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ map : ((R -> R),%) -> %
+ monomial? : % -> Boolean
+ ?*? : (Fraction Integer,%) -> % if R has ALGEBRA FRAC INT
+\end{verbatim}
+
+These exports come from \refto{Ring}():
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ characteristic : () -> NonNegativeInteger
+ coerce : % -> OutputForm
+ coerce : Integer -> %                
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+These exports come from \refto{BiModule}(R:Ring,R:Ring):
+\begin{verbatim}
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from \refto{IntegralDomain}():
+\begin{verbatim}
+ associates? : (%,%) -> Boolean if R has INTDOM
+ coerce : % -> % if R has INTDOM
+ exquo : (%,%) -> Union(%,"failed") if R has INTDOM
+ unit? : % -> Boolean if R has INTDOM
+ unitCanonical : % -> % if R has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) if R has INTDOM
+\end{verbatim}
+
+These exports come from \refto{CharacteristicNonZero}():
+\begin{verbatim}
+ charthRoot : % -> Union(%,"failed") if R has CHARNZ
+\end{verbatim}
+
+These exports come from \refto{CommutativeRing}():
+\begin{verbatim}
+ coerce : R -> % if R has COMRING
+\end{verbatim}
+
+These exports come from \refto{Algebra}(Fraction(Integer)):
+\begin{verbatim}
+ coerce : Fraction Integer -> % if R has ALGEBRA FRAC INT
+ ?*? : (%,Fraction Integer) -> % if R has ALGEBRA FRAC INT
+\end{verbatim}
+
+<<category AMR AbelianMonoidRing>>=
+)abbrev category AMR AbelianMonoidRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Abelian monoid ring elements (not necessarily of finite support)
+++ of this ring are of the form formal SUM (r_i * e_i)
+++ where the r_i are coefficents and the e_i, elements of the
+++ ordered abelian monoid, are thought of as exponents or monomials.
+++ The monomials commute with each other, and with
+++ the coefficients (which themselves may or may not be commutative).
+++ See \spadtype{FiniteAbelianMonoidRing} for the case of finite support
+++ a useful common model for polynomials and power series.
+++ Conceptually at least, only the non-zero terms are ever operated on.
+AbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
+     Join(Ring,BiModule(R,R)) with
+  leadingCoefficient: % -> R
+    ++ leadingCoefficient(p) returns the coefficient highest 
+    ++ degree term of p.
+  leadingMonomial: % -> %
+    ++ leadingMonomial(p) returns the monomial of p with the highest degree.
+  degree: % -> E
+    ++ degree(p) returns the maximum of the exponents of the terms of p.
+  map: (R -> R, %) -> %
+    ++ map(fn,u) maps function fn onto the coefficients
+    ++ of the non-zero monomials of u.
+  monomial?: % -> Boolean
+    ++ monomial?(p) tests if p is a single monomial.
+  monomial: (R,E) -> %
+    ++ monomial(r,e) makes a term from a coefficient r and an exponent e.
+  reductum: % -> %
+    ++ reductum(u) returns u minus its leading monomial
+    ++ returns zero if handed the zero element.
+  coefficient: (%,E) -> R
+    ++ coefficient(p,e) extracts the coefficient of the monomial with
+    ++ exponent e from polynomial p, or returns zero if exponent 
+    ++ is not present.
+  if R has Field then "/": (%,R) -> %
+    ++ p/c divides p by the coefficient c.
+  if R has CommutativeRing then
+     CommutativeRing
+     Algebra R
+  if R has CharacteristicZero then CharacteristicZero
+  if R has CharacteristicNonZero then CharacteristicNonZero
+  if R has IntegralDomain then IntegralDomain
+  if R has Algebra Fraction Integer then Algebra Fraction Integer
+ add
+  monomial? x == zero? reductum x
+
+  map(fn:R -> R, x: %) ==
+        -- this default definition assumes that reductum is cheap
+     zero? x => 0
+     r:=fn leadingCoefficient x
+     zero? r => map(fn,reductum x)
+     monomial(r, degree x) + map(fn,reductum x)
+
+  if R has Algebra Fraction Integer then
+    q:Fraction(Integer) * p:% == map(q * #1, p)
+
+@
+<<AMR.dotabb>>=
+"AMR"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=AMR"];
+"AMR" -> "RING"
+"AMR" -> "BMODULE"
+"AMR" -> "INTDOM"
+"AMR" -> "CHARNZ"
+"AMR" -> "COMRING"
+"AMR" -> "ALGEBRA"
+
+@
+<<AMR.dotfull>>=
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=AMR"];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "Ring()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BiModule(a:Ring,b:OrderedAbelianMonoid)"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+@
+<<AMR.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BIMODULE..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+"IntegralDomain()" [color=lightblue];
+"IntegralDomain()" -> "CommutativeRing()"
+"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
+"IntegralDomain()" -> "EntireRing()"
+
+"EntireRing()" [color=lightblue];
+"EntireRing()" -> "RING..."
+"EntireRing()" -> "BIMODULE..."
+
+"CharacteristicNonZero()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
+"CharacteristicNonZero()" -> "RING..."
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "RING..."
+"Algebra(a:CommutativeRing)" -> "MODULE..."
+
+"CommutativeRing()" [color=lightblue];
+"CommutativeRing()" -> "RING..."
+"CommutativeRing()" -> "BIMODULE..."
+
+"BIMODULE..." [color=lightblue];
+"RING..." [color=lightblue];
+"MODULE..." [color=lightblue];
+}
+
+@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FortranMachineTypeCategory}{FMTC}
 \pagepic{ps/v102fortranmachinetypecategory.ps}{FMTC}{0.40}
@@ -35655,6 +37358,7 @@ GcdDomain(): Category == IntegralDomain with
 @
 <<GCDDOM.dotabb>>=
 "GCDDOM"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=GCDDOM"];
 "GCDDOM" -> "INTDOM"
 
 @
@@ -35703,493 +37407,6 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{OctonionCategory}{OC}
-\pagepic{ps/v102octonioncategory.ps}{OC}{1.00}
-
-{\bf See:}\\
-\pagefrom{Algebra}{ALGEBRA}
-\pagefrom{FullyEvalableOver}{FEVALAB}
-\pagefrom{FullyRetractableTo}{FRETRCT}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{OC}{0} &
-\cross{OC}{1} &
-\cross{OC}{abs} &
-\cross{OC}{characteristic} &
-\cross{OC}{charthRoot} \\
-\cross{OC}{coerce} &
-\cross{OC}{conjugate} &
-\cross{OC}{convert} &
-\cross{OC}{eval} &
-\cross{OC}{hash} \\
-\cross{OC}{imagE} &
-\cross{OC}{imagI} &
-\cross{OC}{imagJ} &
-\cross{OC}{imagK} &
-\cross{OC}{imagi} \\
-\cross{OC}{imagj} &
-\cross{OC}{imagk} &
-\cross{OC}{index} &
-\cross{OC}{inv} &
-\cross{OC}{latex} \\
-\cross{OC}{lookup} &
-\cross{OC}{map} &
-\cross{OC}{max} &
-\cross{OC}{min} &
-\cross{OC}{norm} \\
-\cross{OC}{octon} &
-\cross{OC}{one?} &
-\cross{OC}{random} &
-\cross{OC}{rational} &
-\cross{OC}{rational?} \\
-\cross{OC}{rationalIfCan} &
-\cross{OC}{real} &
-\cross{OC}{recip} &
-\cross{OC}{retract} &
-\cross{OC}{retractIfCan} \\
-\cross{OC}{sample} &
-\cross{OC}{size} &
-\cross{OC}{subtractIfCan} &
-\cross{OC}{zero?} &
-\cross{OC}{?*?} \\
-\cross{OC}{?**?} &
-\cross{OC}{?+?} &
-\cross{OC}{?-?} &
-\cross{OC}{-?} &
-\cross{OC}{?=?} \\
-\cross{OC}{?\^{}?} &
-\cross{OC}{?\~{}=?} &
-\cross{OC}{?$<$?} &
-\cross{OC}{?$<=$?} &
-\cross{OC}{?$>$?} \\
-\cross{OC}{?$>=$?} &
-\cross{OC}{?.?} &&&
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{OC}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item {\bf \cross{OC}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item {\bf \cross{OC}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- imagi : % -> R
- imagj : % -> R                       
- imagk : % -> R
- imagE : % -> R
- imagI : % -> R                       
- imagJ : % -> R
- imagK : % -> R                       
- octon : (R,R,R,R,R,R,R,R) -> %       
- real : % -> R                        
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- abs : % -> R if R has RNS
- characteristic : () -> NonNegativeInteger
- coerce : R -> %                      
- coerce : Integer -> %
- coerce : % -> OutputForm             
- conjugate : % -> %
- convert : % -> InputForm if R has KONVERT INFORM
- inv : % -> % if R has FIELD          
- map : ((R -> R),%) -> %              
- norm : % -> R
- rational : % -> Fraction Integer if R has INS
- rational? : % -> Boolean if R has INS
- rationalIfCan : % -> Union(Fraction Integer,"failed") if R has INS
- retract : % -> R                     
- retractIfCan : % -> Union(R,"failed")
- zero? : % -> Boolean                 
- ?<? : (%,%) -> Boolean if R has ORDSET
- ?=? : (%,%) -> Boolean
- ?+? : (%,%) -> %                     
- -? : % -> %                          
- ?*? : (R,%) -> %                     
- ?*? : (Integer,%) -> %
-\end{verbatim}
-
-These exports come from \refto{Algebra}(R:CommutativeRing):
-\begin{verbatim}
- 0 : () -> %
- 1 : () -> %                          
- hash : % -> SingleInteger            
- latex : % -> String
- one? : % -> Boolean
- recip : % -> Union(%,"failed")
- sample : () -> %
- subtractIfCan : (%,%) -> Union(%,"failed")
- ?~=? : (%,%) -> Boolean
- ?*? : (NonNegativeInteger,%) -> %
- ?*? : (PositiveInteger,%) -> %       
- ?*? : (%,%) -> %                     
- ?-? : (%,%) -> %
- ?**? : (%,NonNegativeInteger) -> %
- ?**? : (%,PositiveInteger) -> %
- ?^? : (%,PositiveInteger) -> %       
- ?^? : (%,NonNegativeInteger) -> %
- ?*? : (%,R) -> %
-\end{verbatim}
-
-These exports come from \refto{FullyRetractableTo}(R:CommutativeRing):
-\begin{verbatim}
- coerce : Fraction Integer -> % if R has RETRACT FRAC INT
- retract : % -> Fraction Integer if R has RETRACT FRAC INT
- retract : % -> Integer if R has RETRACT INT
- retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
- retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
-\end{verbatim}
-
-These exports come from \refto{FullyEvalableOver}(R:CommutativeRing):
-\begin{verbatim}
- eval : (%,Equation R) -> % if R has EVALAB R
- eval : (%,List Symbol,List R) -> % if R has IEVALAB(SYMBOL,R)
- eval : (%,List Equation R) -> % if R has EVALAB R
- eval : (%,R,R) -> % if R has EVALAB R
- eval : (%,List R,List R) -> % if R has EVALAB R
- eval : (%,Symbol,R) -> % if R has IEVALAB(SYMBOL,R)
- ?.? : (%,R) -> % if R has ELTAB(R,R)
-\end{verbatim}
-
-These exports come from \refto{Finite}():
-\begin{verbatim}
- index : PositiveInteger -> % if R has FINITE
- lookup : % -> PositiveInteger if R has FINITE
- random : () -> % if R has FINITE
- size : () -> NonNegativeInteger if R has FINITE
-\end{verbatim}
-
-These exports come from \refto{OrderedSet}():
-\begin{verbatim}
- max : (%,%) -> % if R has ORDSET
- min : (%,%) -> % if R has ORDSET
- ?<=? : (%,%) -> Boolean if R has ORDSET
- ?>? : (%,%) -> Boolean if R has ORDSET
- ?>=? : (%,%) -> Boolean if R has ORDSET
-\end{verbatim}
-
-These exports come from \refto{CharacteristicNonZero}():
-\begin{verbatim}
- charthRoot : % -> Union(%,"failed") if R has CHARNZ
-\end{verbatim}
-
-<<category OC OctonionCategory>>=
-)abbrev category OC OctonionCategory
-++ Author: R. Wisbauer, J. Grabmeier
-++ Date Created: 05 September 1990
-++ Date Last Updated: 19 September 1990
-++ Basic Operations: _+, _*, octon, real, imagi, imagj, imagk,
-++  imagE, imagI, imagJ, imagK
-++ Related Constructors: QuaternionCategory
-++ Also See: 
-++ AMS Classifications:
-++ Keywords: octonion, non-associative algebra, Cayley-Dixon  
-++ References: e.g. I.L Kantor, A.S. Solodovnikov:
-++  Hypercomplex Numbers, Springer Verlag Heidelberg, 1989,
-++  ISBN 0-387-96980-2
-++ Description:
-++  OctonionCategory gives the categorial frame for the 
-++  octonions, and eight-dimensional non-associative algebra, 
-++  doubling the the quaternions in the same way as doubling
-++  the Complex numbers to get the quaternions.
--- Examples: octonion.input
- 
-OctonionCategory(R: CommutativeRing): Category ==
-  -- we are cheating a little bit, algebras in \Language{}
-  -- are mainly considered to be associative, but that's not 
-  -- an attribute and we can't guarantee that there is no piece
-  -- of code which implicitly
-  -- uses this. In a later version we shall properly combine
-  -- all this code in the context of general, non-associative
-  -- algebras, which are meanwhile implemented in \Language{}
-  Join(Algebra R, FullyRetractableTo R, FullyEvalableOver R) with
-     conjugate: % -> % 
-       ++ conjugate(o) negates the imaginary parts i,j,k,E,I,J,K of octonian o.
-     real:    % -> R 
-       ++ real(o) extracts real part of octonion o.
-     imagi:   % -> R      
-       ++ imagi(o) extracts the i part of octonion o.
-     imagj:   % -> R                
-       ++ imagj(o) extracts the j part of octonion o.
-     imagk:   % -> R 
-       ++ imagk(o) extracts the k part of octonion o.
-     imagE:   % -> R 
-       ++ imagE(o) extracts the imaginary E part of octonion o.
-     imagI:   % -> R              
-       ++ imagI(o) extracts the imaginary I part of octonion o.
-     imagJ:   % -> R      
-       ++ imagJ(o) extracts the imaginary J part of octonion o.
-     imagK:   % -> R
-       ++ imagK(o) extracts the imaginary K part of octonion o.
-     norm:    % -> R 
-       ++ norm(o) returns the norm of an octonion, equal to
-       ++ the sum of the squares
-       ++ of its coefficients.
-     octon: (R,R,R,R,R,R,R,R) -> %   
-       ++ octon(re,ri,rj,rk,rE,rI,rJ,rK) constructs an octonion 
-       ++ from scalars. 
-     if R has Finite then Finite
-     if R has OrderedSet then OrderedSet
-     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
-     if R has CharacteristicZero then CharacteristicZero
-     if R has CharacteristicNonZero then CharacteristicNonZero
-     if R has RealNumberSystem then
-       abs:   % -> R 
-         ++ abs(o) computes the absolute value of an octonion, equal to 
-         ++ the square root of the \spadfunFrom{norm}{Octonion}.
-     if R has IntegerNumberSystem then
-       rational?    : % -> Boolean
-         ++ rational?(o) tests if o is rational, i.e. that all seven
-         ++ imaginary parts are 0.
-       rational     : % -> Fraction Integer
-         ++ rational(o) returns the real part if all seven 
-         ++ imaginary parts are 0.
-         ++ Error: if o is not rational.
-       rationalIfCan: % -> Union(Fraction Integer, "failed")
-         ++ rationalIfCan(o) returns the real part if
-         ++ all seven imaginary parts are 0, and "failed" otherwise.
-     if R has Field then
-       inv : % -> % 
-         ++ inv(o) returns the inverse of o if it exists.
- add
-     characteristic() == 
-       characteristic()$R
-
-     conjugate x ==
-       octon(real x, - imagi x, - imagj x, - imagk x, - imagE x,_
-       - imagI x, - imagJ x, - imagK x)
-
-     map(fn, x)       ==
-       octon(fn real x,fn imagi x,fn imagj x,fn imagk x, fn imagE x,_
-       fn imagI x, fn imagJ x,fn imagK x)
-
-     norm x ==
-       real x * real x + imagi x * imagi x + _
-       imagj x * imagj x + imagk x * imagk x + _
-       imagE x * imagE x + imagI x * imagI x + _
-       imagJ x * imagJ x + imagK x * imagK x
-
-     x = y            ==
-       (real x = real y) and (imagi x = imagi y) and _
-       (imagj x = imagj y) and (imagk x = imagk y) and _
-       (imagE x = imagE y) and (imagI x = imagI y) and _
-       (imagJ x = imagJ y) and (imagK x = imagK y)
-
-     x + y            ==
-       octon(real x + real y, imagi x + imagi y,_
-       imagj x + imagj y, imagk x + imagk y,_
-       imagE x + imagE y, imagI x + imagI y,_
-       imagJ x + imagJ y, imagK x + imagK y)
-
-     - x              ==
-       octon(- real x, - imagi x, - imagj x, - imagk x,_
-       - imagE x, - imagI x, - imagJ x, - imagK x)
-
-     r:R * x:%        ==
-       octon(r * real x, r * imagi x, r * imagj x, r * imagk x,_
-       r * imagE x, r * imagI x, r * imagJ x, r * imagK x)
-
-     n:Integer * x:%  ==
-       octon(n * real x, n * imagi x, n * imagj x, n * imagk x,_
-       n * imagE x, n * imagI x, n * imagJ x, n * imagK x)
-
-     coerce(r:R)      ==
-       octon(r,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
-
-     coerce(n:Integer)      ==
-       octon(n :: R,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
-
-     zero? x ==
-       zero? real x and zero? imagi x and _
-       zero? imagj x and zero? imagk x and _
-       zero? imagE x and zero? imagI x and _
-       zero? imagJ x and zero? imagK x
-
-     retract(x):R ==
-       not (zero? imagi x and zero? imagj x and zero? imagk x and _
-       zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
-         error "Cannot retract octonion."
-       real x
-
-     retractIfCan(x):Union(R,"failed") ==
-       not (zero? imagi x and zero? imagj x and zero? imagk x and _
-       zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
-         "failed"
-       real x
- 
-     coerce(x:%):OutputForm ==
-         part,z : OutputForm
-         y : %
-         zero? x => (0$R) :: OutputForm
-         not zero?(real x) =>
-           y := octon(0$R,imagi(x),imagj(x),imagk(x),imagE(x),
-             imagI(x),imagJ(x),imagK(x))
-           zero? y => real(x) :: OutputForm
-           (real(x) :: OutputForm) + (y :: OutputForm)
-         -- we know that the real part is 0
-         not zero?(imagi(x)) =>
-           y := octon(0$R,0$R,imagj(x),imagk(x),imagE(x),
-             imagI(x),imagJ(x),imagK(x))
-           z :=
-             part := "i"::Symbol::OutputForm
---             one? imagi(x) => part
-             (imagi(x) = 1) => part
-             (imagi(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part and i part are 0
-         not zero?(imagj(x)) =>
-           y := octon(0$R,0$R,0$R,imagk(x),imagE(x),
-             imagI(x),imagJ(x),imagK(x))
-           z :=
-             part := "j"::Symbol::OutputForm
---             one? imagj(x) => part
-             (imagj(x) = 1) => part
-             (imagj(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part and i and j parts are 0
-         not zero?(imagk(x)) =>
-           y := octon(0$R,0$R,0$R,0$R,imagE(x),
-             imagI(x),imagJ(x),imagK(x))
-           z :=
-             part := "k"::Symbol::OutputForm
---             one? imagk(x) => part
-             (imagk(x) = 1) => part
-             (imagk(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part,i,j,k parts are 0
-         not zero?(imagE(x)) =>
-           y := octon(0$R,0$R,0$R,0$R,0$R,
-             imagI(x),imagJ(x),imagK(x))
-           z :=
-             part := "E"::Symbol::OutputForm
---             one? imagE(x) => part
-             (imagE(x) = 1) => part
-             (imagE(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part,i,j,k,E parts are 0
-         not zero?(imagI(x)) =>
-           y := octon(0$R,0$R,0$R,0$R,0$R,0$R,imagJ(x),imagK(x))
-           z :=
-             part := "I"::Symbol::OutputForm
---             one? imagI(x) => part
-             (imagI(x) = 1) => part
-             (imagI(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part,i,j,k,E,I parts are 0
-         not zero?(imagJ(x)) =>
-           y := octon(0$R,0$R,0$R,0$R,0$R,0$R,0$R,imagK(x))
-           z :=
-             part := "J"::Symbol::OutputForm
---             one? imagJ(x) => part
-             (imagJ(x) = 1) => part
-             (imagJ(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part,i,j,k,E,I,J parts are 0
-         part := "K"::Symbol::OutputForm
---         one? imagK(x) => part
-         (imagK(x) = 1) => part
-         (imagK(x) :: OutputForm) * part
- 
-     if R has Field then
-       inv x ==
-         (norm x) = 0 => error "This octonion is not invertible."
-         (inv norm x) * conjugate x
-
-     if R has ConvertibleTo InputForm then
-       convert(x:%):InputForm ==
-         l : List InputForm := [convert("octon" :: Symbol),
-           convert(real x)$R, convert(imagi x)$R, convert(imagj x)$R,_
-             convert(imagk x)$R, convert(imagE x)$R,_
-             convert(imagI x)$R, convert(imagJ x)$R,_
-             convert(imagK x)$R]
-         convert(l)$InputForm
-
-     if R has OrderedSet then
-       x < y ==
-         real x = real y =>
-          imagi x = imagi y =>
-           imagj x = imagj y =>
-            imagk x = imagk y =>
-             imagE x = imagE y =>
-              imagI x = imagI y =>
-               imagJ x = imagJ y =>
-                imagK x < imagK y
-               imagJ x < imagJ y
-              imagI x < imagI y
-             imagE x < imagE y
-            imagk x < imagk y 
-           imagj x < imagj y 
-          imagi x < imagi y 
-         real x < real y
- 
-     if R has RealNumberSystem then
-       abs x == sqrt norm x
- 
-     if R has IntegerNumberSystem then
-       rational? x ==
-         (zero? imagi x) and (zero? imagj x) and (zero? imagk x) and _ 
-         (zero? imagE x) and (zero? imagI x) and (zero? imagJ x) and _
-         (zero? imagK x)
-
-       rational  x ==
-         rational? x => rational real x
-         error "Not a rational number"
-
-       rationalIfCan x ==
-         rational? x => rational real x
-         "failed"
-
-@
-<<OC.dotabb>>=
-"OC"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=OC"];
-"OC" -> "ALGEBRA"
-"OC" -> "FEVALAB"
-"OC" -> "FRETRCT"
-
-@
-<<OC.dotfull>>=
-"OctonionCategory(a:CommutativeRing)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=OC"];
-"OctonionCategory(a:CommutativeRing)" -> "Algebra(a:CommutativeRing)"
-"OctonionCategory(a:CommutativeRing)" -> "FullyEvalableOver(CommutativeRing)"
-"OctonionCategory(a:CommutativeRing)" ->
-   "FullyRetractableTo(a:CommutativeRing)"
-
-@
-<<OC.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"OctonionCategory(a:CommutativeRing)" [color=lightblue];
-"OctonionCategory(a:CommutativeRing)" -> "ALGEBRA..."
-"OctonionCategory(a:CommutativeRing)" -> "FEVALAB..."
-"OctonionCategory(a:CommutativeRing)" -> "FRETRCT..."
-
-"ALGEBRA..." [color=lightblue];
-"FEVALAB..." [color=lightblue];
-"FRETRCT..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OrderedIntegralDomain}{OINTDOM}
 \pagepic{ps/v102orderedintegraldomain.ps}{OINTDOM}{0.45}
 
@@ -36383,7 +37600,381 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 14}
+\chapter{Category Layer 13}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{FiniteAbelianMonoidRing}{FAMR}
+\pagepic{ps/v102finiteabelianmonoidring.ps}{FAMR}{0.40}
+
+{\bf See:}\\
+\pageto{PolynomialCategory}{POLYCAT}
+\pagefrom{AbelianMonoidRing}{AMR}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{FAMR}{0} &
+\cross{FAMR}{1} &
+\cross{FAMR}{associates?} &
+\cross{FAMR}{binomThmExpt} \\
+\cross{FAMR}{characteristic} &
+\cross{FAMR}{charthRoot} &
+\cross{FAMR}{coefficient} &
+\cross{FAMR}{coefficients} \\
+\cross{FAMR}{coerce} &
+\cross{FAMR}{content} &
+\cross{FAMR}{degree} &
+\cross{FAMR}{exquo} \\
+\cross{FAMR}{ground} &
+\cross{FAMR}{ground?} &
+\cross{FAMR}{hash} &
+\cross{FAMR}{latex} \\
+\cross{FAMR}{leadingCoefficient} &
+\cross{FAMR}{leadingMonomial} &
+\cross{FAMR}{map} &
+\cross{FAMR}{mapExponents} \\
+\cross{FAMR}{minimumDegree} &
+\cross{FAMR}{monomial} &
+\cross{FAMR}{monomial?} &
+\cross{FAMR}{numberOfMonomials} \\
+\cross{FAMR}{one?} &
+\cross{FAMR}{pomopo!} &
+\cross{FAMR}{primitivePart} &
+\cross{FAMR}{recip} \\
+\cross{FAMR}{reductum} &
+\cross{FAMR}{retract} &
+\cross{FAMR}{retractIfCan} &
+\cross{FAMR}{sample} \\
+\cross{FAMR}{subtractIfCan} &
+\cross{FAMR}{unit?} &
+\cross{FAMR}{unitCanonical} &
+\cross{FAMR}{unitNormal} \\
+\cross{FAMR}{zero?} &
+\cross{FAMR}{?*?} &
+\cross{FAMR}{?**?} &
+\cross{FAMR}{?+?} \\
+\cross{FAMR}{?-?} &
+\cross{FAMR}{-?} &
+\cross{FAMR}{?=?} &
+\cross{FAMR}{?\^{}?} \\
+\cross{FAMR}{?\~{}=?} &
+\cross{FAMR}{?/?} &&
+\end{tabular}
+
+{\bf Attributes exported:}
+\begin{itemize}
+\item if \$ has CommutativeRing then commutative(``*'') where
+{\bf \cross{FAMR}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\item if \$ has IntegralDomain then noZeroDivisors where
+{\bf \cross{FAMR}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{FAMR}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{FAMR}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{FAMR}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ minimumDegree : % -> E
+ numberOfMonomials : % -> NonNegativeInteger
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ binomThmExpt : (%,%,NonNegativeInteger) -> % 
+     if R has COMRING
+ coefficients : % -> List R           
+ content : % -> R if R has GCDDOM
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ ground : % -> R
+ ground? : % -> Boolean               
+ mapExponents : ((E -> E),%) -> %     
+ pomopo! : (%,R,E,%) -> %
+ primitivePart : % -> % if R has GCDDOM
+ ?/? : (%,R) -> % if R has FIELD
+\end{verbatim}
+
+These exports come from \refto{AbelianMonoidRing}(R,E)\\
+where R:Ring and E:OrderedAbelianMonoid:
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ associates? : (%,%) -> Boolean if R has INTDOM
+ characteristic : () -> NonNegativeInteger
+ charthRoot : % -> Union(%,"failed") if R has CHARNZ
+ coefficient : (%,E) -> R
+ coerce : R -> %
+ coerce : Fraction Integer -> % 
+     if R has RETRACT FRAC INT 
+     or R has ALGEBRA FRAC INT
+ coerce : % -> % if R has INTDOM
+ coerce : % -> OutputForm
+ coerce : Integer -> %                
+ degree : % -> E                      
+ exquo : (%,%) -> Union(%,"failed") if R has INTDOM
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ leadingCoefficient : % -> R
+ leadingMonomial : % -> %             
+ map : ((R -> R),%) -> %
+ monomial : (R,E) -> %                
+ monomial? : % -> Boolean
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")       
+ reductum : % -> %
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ unit? : % -> Boolean if R has INTDOM
+ unitCanonical : % -> % if R has INTDOM
+ unitNormal :
+    % -> Record(unit: %,canonical: %,associate: %) 
+    if R has INTDOM
+ zero? : % -> Boolean                 
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+ ?*? : (Fraction Integer,%) -> % if R has ALGEBRA FRAC INT
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
+ ?*? : (%,Fraction Integer) -> % if R has ALGEBRA FRAC INT
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(R:Ring):
+\begin{verbatim}
+ retract : % -> Fraction Integer 
+     if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retract : % -> R                     
+ retractIfCan : % -> Union(R,"failed")
+ retractIfCan : % -> Union(Integer,"failed") 
+     if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") 
+     if R has RETRACT FRAC INT
+\end{verbatim}
+
+<<category FAMR FiniteAbelianMonoidRing>>=
+)abbrev category FAMR FiniteAbelianMonoidRing
+++ Author:
+++ Date Created:
+++ Date Last Updated: 14.08.2000 Exported pomopo! and binomThmExpt [MMM]
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: This category is
+++ similar to AbelianMonoidRing, except that the sum is assumed to be finite.
+++ It is a useful model for polynomials,
+++ but is somewhat more general.
+
+FiniteAbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
+   Join(AbelianMonoidRing(R,E),FullyRetractableTo R) with
+    ground?: % -> Boolean
+      ++ ground?(p) tests if polynomial p is a member of the 
+      ++ coefficient ring.
+      -- can't be defined earlier, since a power series
+      -- might not know if there were other terms or not
+    ground: % -> R
+      ++ ground(p) retracts polynomial p to the coefficient ring.
+    coefficients: % -> List R
+      ++ coefficients(p) gives the list of non-zero coefficients 
+      ++ of polynomial p.
+    numberOfMonomials: % -> NonNegativeInteger
+      ++ numberOfMonomials(p) gives the number of non-zero monomials 
+      ++ in polynomial p.
+    minimumDegree: % -> E
+      ++ minimumDegree(p) gives the least exponent of a non-zero term 
+      ++ of polynomial p. Error: if applied to 0.
+    mapExponents: (E -> E, %) -> %
+      ++ mapExponents(fn,u) maps function fn onto the exponents
+      ++ of the non-zero monomials of polynomial u.
+    pomopo!: (%,R,E,%) -> %
+      ++ \spad{pomopo!(p1,r,e,p2)} returns \spad{p1 + monomial(e,r) * p2}
+      ++ and may use \spad{p1} as workspace. The constaant \spad{r} is
+      ++ assumed to be nonzero.
+    if R has CommutativeRing then
+       binomThmExpt: (%,%,NonNegativeInteger) -> %
+         ++ \spad{binomThmExpt(p,q,n)} returns \spad{(x+y)^n}
+         ++ by means of the binomial theorem trick.
+    if R has IntegralDomain then
+       "exquo": (%,R) -> Union(%,"failed")
+       ++ exquo(p,r) returns the exact quotient of polynomial p by r, 
+       ++ or "failed" if none exists.
+    if R has GcdDomain then
+       content: % -> R
+         ++ content(p) gives the gcd of the coefficients of polynomial p.
+       primitivePart: % -> %
+         ++ primitivePart(p) returns the unit normalized form of polynomial p
+         ++ divided by the content of p.
+  add
+    pomopo!(p1,r,e,p2) == p1 + r * mapExponents(#1+e,p2)
+
+    if R has CommutativeRing then 
+       binomThmExpt(x,y,nn) ==
+               nn = 0 => 1$%
+               ans,xn,yn: %
+               bincoef: Integer
+               powl: List(%):= [x]
+               for i in 2..nn repeat powl:=[x * powl.first, :powl]
+               yn:=y; ans:=powl.first; i:=1; bincoef:=nn
+               for xn in powl.rest repeat
+                  ans:= bincoef * xn * yn + ans
+                  bincoef:= (nn-i) * bincoef quo (i+1);  i:= i+1
+                  -- last I and BINCOEF unused
+                  yn:= y * yn
+               ans + yn
+    ground? x ==
+      retractIfCan(x)@Union(R,"failed") case "failed" => false
+      true
+
+    ground x == retract(x)@R
+
+    mapExponents (fn:E -> E, x: %) ==
+         -- this default definition assumes that reductum is cheap
+       zero? x => 0
+       monomial(leadingCoefficient x,fn degree x)+mapExponents(fn,reductum x)
+
+    coefficients x ==
+      zero? x => empty()
+      concat(leadingCoefficient x, coefficients reductum x)
+
+    if R has Field then
+       x/r == map(#1/r,x)
+
+    if R has IntegralDomain then
+       x exquo r ==
+          -- probably not a very good definition in most special cases
+          zero? x => 0
+          ans:% :=0
+          t:=leadingCoefficient x exquo r
+          while not (t case "failed") and not zero? x repeat
+            ans:=ans+monomial(t::R,degree x)
+            x:=reductum x
+            if not zero? x then t:=leadingCoefficient x exquo r
+          t case "failed" => "failed"
+          ans
+
+    if R has GcdDomain then
+       content x ==       -- this assumes  reductum is cheap
+          zero? x => 0
+          r:=leadingCoefficient x
+          x:=reductum x
+--          while not zero? x and not one? r repeat
+          while not zero? x and not (r = 1) repeat
+            r:=gcd(r,leadingCoefficient x)
+            x:=reductum x
+          r
+
+       primitivePart x ==
+          zero? x => x
+          c := content x
+          unitCanonical((x exquo c)::%)
+
+@
+<<FAMR.dotabb>>=
+"FAMR"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FAMR"];
+"FAMR" -> "AMR"
+"FAMR" -> "FRETRCT"
+
+@
+<<FAMR.dotfull>>=
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FAMR"];
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
+    "FullyRetractableTo(a:Ring)"
+
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoidSup)" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=FAMR"];
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoidSup)" ->
+    "FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+
+@
+<<FAMR.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+"FiniteAbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" ->
+    "FullyRetractableTo(a:Ring)"
+
+"FullyRetractableTo(a:Ring)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=FRETRCT"];
+"FullyRetractableTo(a:Ring)" -> "FullyRetractableTo(a:Type)"
+
+"FullyRetractableTo(a:Type)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FRETRCT"];
+"FullyRetractableTo(a:Type)" -> "RETRACT..."
+
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BIMODULE..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+"IntegralDomain()" [color=lightblue];
+"IntegralDomain()" -> "CommutativeRing()"
+"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
+"IntegralDomain()" -> "EntireRing()"
+
+"EntireRing()" [color=lightblue];
+"EntireRing()" -> "RING..."
+"EntireRing()" -> "BIMODULE..."
+
+"CharacteristicNonZero()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
+"CharacteristicNonZero()" -> "RING..."
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "RING..."
+"Algebra(a:CommutativeRing)" -> "MODULE..."
+
+"CommutativeRing()" [color=lightblue];
+"CommutativeRing()" -> "RING..."
+"CommutativeRing()" -> "BIMODULE..."
+
+"RETRACT..." [color=lightblue];
+"BIMODULE..." [color=lightblue];
+"RING..." [color=lightblue];
+"MODULE..." [color=lightblue];
+}
+
+@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{IntervalCategory}{INTCAT}
 \pagepic{ps/v102intervalcategory.ps}{INTCAT}{0.60}
@@ -36733,6 +38324,289 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{PowerSeriesCategory}{PSCAT}
+\pagepic{ps/v102powerseriescategory.ps}{PSCAT}{0.60}
+
+{\bf See:}\\
+\pageto{MultivariateTaylorSeriesCategory}{MTSCAT}
+\pageto{UnivariatePowerSeriesCategory}{UPSCAT}
+\pagefrom{AbelianMonoidRing}{AMR}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{PSCAT}{0} &
+\cross{PSCAT}{1} &
+\cross{PSCAT}{associates?} &
+\cross{PSCAT}{characteristic} &
+\cross{PSCAT}{charthRoot} \\
+\cross{PSCAT}{coefficient} &
+\cross{PSCAT}{coerce} &
+\cross{PSCAT}{coerce} &
+\cross{PSCAT}{coerce} &
+\cross{PSCAT}{coerce} \\
+\cross{PSCAT}{coerce} &
+\cross{PSCAT}{complete} &
+\cross{PSCAT}{degree} &
+\cross{PSCAT}{exquo} &
+\cross{PSCAT}{hash} \\
+\cross{PSCAT}{latex} &
+\cross{PSCAT}{leadingCoefficient} &
+\cross{PSCAT}{leadingMonomial} &
+\cross{PSCAT}{map} &
+\cross{PSCAT}{monomial} \\
+\cross{PSCAT}{monomial} &
+\cross{PSCAT}{monomial} &
+\cross{PSCAT}{monomial?} &
+\cross{PSCAT}{one?} &
+\cross{PSCAT}{pole?} \\
+\cross{PSCAT}{recip} &
+\cross{PSCAT}{reductum} &
+\cross{PSCAT}{sample} &
+\cross{PSCAT}{subtractIfCan} &
+\cross{PSCAT}{variables} \\
+\cross{PSCAT}{unit?} &
+\cross{PSCAT}{unitCanonical} &
+\cross{PSCAT}{unitNormal} &
+\cross{PSCAT}{zero?} &
+\cross{PSCAT}{?*?} \\
+\cross{PSCAT}{?**?} &
+\cross{PSCAT}{?+?} &
+\cross{PSCAT}{?-?} &
+\cross{PSCAT}{-?} &
+\cross{PSCAT}{?=?} \\
+\cross{PSCAT}{?\~{}=?} &
+\cross{PSCAT}{?/?} &
+\cross{PSCAT}{?\^{}?} &&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{PSCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{PSCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{PSCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item if \#1 has IntegralDomain then noZeroDivisors where
+{\bf \cross{PSCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item if \#1 has CommutativeRing then commutative(``*'') where
+{\bf \cross{PSCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ complete : % -> %                    
+ degree : % -> Expon
+ leadingCoefficient : % -> Coef       
+ leadingMonomial : % -> %
+ monomial : (%,List Var,List Expon) -> %
+ monomial : (%,Var,Expon) -> %
+ pole? : % -> Boolean
+ variables : % -> List Var
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ ?*? : (Integer,%) -> %
+ ?*? : (Coef,%) -> %                  
+ ?*? : (%,Coef) -> %
+ ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
+ ?/? : (%,Coef) -> % if Coef has FIELD
+ -? : % -> %                          
+\end{verbatim}
+
+These exports come from \refto{AbelianMonoidRing}(Coef,Expon)\\
+where Coef:Ring and Expon:OrderedAbelianMonoid:
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ associates? : (%,%) -> Boolean if Coef has INTDOM
+ characteristic : () -> NonNegativeInteger
+ charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
+ coefficient : (%,Expon) -> Coef
+ coerce : Coef -> % if Coef has COMRING
+ coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
+ coerce : % -> % if Coef has INTDOM
+ coerce : % -> OutputForm
+ coerce : Integer -> %                
+ exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ hash : % -> SingleInteger            
+ latex : % -> String
+ map : ((Coef -> Coef),%) -> %        
+ monomial : (Coef,Expon) -> %         
+ monomial? : % -> Boolean
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")       
+ reductum : % -> %
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ unit? : % -> Boolean if Coef has INTDOM
+ unitCanonical : % -> % if Coef has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
+     if Coef has INTDOM
+ zero? : % -> Boolean                 
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+\end{verbatim}
+
+<<category PSCAT PowerSeriesCategory>>=
+)abbrev category PSCAT PowerSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 25 February 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: power series
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{PowerSeriesCategory} is the most general power series
+++   category with exponents in an ordered abelian monoid.
+PowerSeriesCategory(Coef,Expon,Var): Category == Definition where
+  Coef  : Ring
+  Expon : OrderedAbelianMonoid
+  Var   : OrderedSet
+  I   ==> Integer
+  RN  ==> Fraction Integer
+
+  Definition ==> AbelianMonoidRing(Coef,Expon) with
+    monomial: (%,Var,Expon) -> %
+      ++ \spad{monomial(a,x,n)} computes \spad{a*x**n}.
+    monomial: (%,List Var,List Expon) -> %
+      ++ \spad{monomial(a,[x1,..,xk],[n1,..,nk])} computes
+      ++ \spad{a * x1**n1 * .. * xk**nk}.
+    leadingMonomial: % -> %
+      ++ leadingMonomial(f) returns the monomial of \spad{f} of lowest order.
+    leadingCoefficient: % -> Coef
+      ++ leadingCoefficient(f) returns the coefficient of the lowest order
+      ++ term of \spad{f}
+    degree : % -> Expon
+      ++ degree(f) returns the exponent of the lowest order term of \spad{f}.
+    variables: % -> List Var
+      ++ \spad{variables(f)} returns a list of the variables occuring in the
+      ++ power series f.
+    pole?: % -> Boolean
+      ++ \spad{pole?(f)} determines if the power series f has a pole.
+    complete: % -> %
+      ++ \spad{complete(f)} causes all terms of f to be computed.
+      ++ Note: this results in an infinite loop
+      ++ if f has infinitely many terms.
+
+   add
+    n:I    * ps:% == (zero? n => 0; map(n * #1,ps))
+
+    r:Coef * ps:% == (zero? r => 0; map(r * #1,ps))
+
+    ps:% * r:Coef == (zero? r => 0; map(#1 * r,ps))
+
+    - ps          == map(- #1,ps)
+
+    if Coef has Algebra Fraction Integer then
+      r:RN * ps:% == (zero? r => 0; map(r * #1,ps))
+
+      ps:% * r:RN == (zero? r => 0; map(#1 * r,ps))
+
+    if Coef has Field then
+      ps:% / r:Coef == map(#1 / r,ps)
+
+@
+<<PSCAT.dotabb>>=
+"PSCAT" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PSCAT"];
+"PSCAT" -> "AMR"
+
+@
+<<PSCAT.dotfull>>=
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=PSCAT"];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=PSCAT"];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+
+"PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=PSCAT"];
+"PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
+  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+
+@
+<<PSCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+ [color=lightblue];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BIMODULE..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+"IntegralDomain()" [color=lightblue];
+"IntegralDomain()" -> "CommutativeRing()"
+"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
+"IntegralDomain()" -> "EntireRing()"
+
+"EntireRing()" [color=lightblue];
+"EntireRing()" -> "RING..."
+"EntireRing()" -> "BIMODULE..."
+
+"CharacteristicNonZero()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
+"CharacteristicNonZero()" -> "RING..."
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "RING..."
+"Algebra(a:CommutativeRing)" -> "MODULE..."
+
+"CommutativeRing()" [color=lightblue];
+"CommutativeRing()" -> "RING..."
+"CommutativeRing()" -> "BIMODULE..."
+
+"BIMODULE..." [color=lightblue];
+"RING..." [color=lightblue];
+"MODULE..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{PrincipalIdealDomain}{PID}
 \pagepic{ps/v102principalidealdomain.ps}{PID}{0.65}
 
@@ -37128,7 +39002,7 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 15}
+\chapter{Category Layer 14}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{EuclideanDomain}{EUCDOM}
 \pagepic{ps/v102euclideandomain.ps}{EUCDOM}{0.65}
@@ -37460,6 +39334,357 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{MultivariateTaylorSeriesCategory}{MTSCAT}
+\pagepic{ps/v102multivariatetaylorseriescategory.ps}{MTSCAT}{1.00}
+
+{\bf See:}\\
+\pagefrom{Evalable}{EVALAB}
+\pagefrom{InnerEvalable}{IEVALAB}
+\pagefrom{PartialDifferentialRing}{PDRING}
+\pagefrom{PowerSeriesCategory}{PSCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{MTSCAT}{0} &
+\cross{MTSCAT}{1} &
+\cross{MTSCAT}{acos} &
+\cross{MTSCAT}{acosh} &
+\cross{MTSCAT}{acot} \\
+\cross{MTSCAT}{acoth} &
+\cross{MTSCAT}{acsc} &
+\cross{MTSCAT}{acsch} &
+\cross{MTSCAT}{asec} &
+\cross{MTSCAT}{asech} \\
+\cross{MTSCAT}{asin} &
+\cross{MTSCAT}{asinh} &
+\cross{MTSCAT}{associates?} &
+\cross{MTSCAT}{atan} &
+\cross{MTSCAT}{atanh} \\
+\cross{MTSCAT}{characteristic} &
+\cross{MTSCAT}{charthRoot} &
+\cross{MTSCAT}{coefficient} &
+\cross{MTSCAT}{coerce} &
+\cross{MTSCAT}{complete} \\
+\cross{MTSCAT}{cos} &
+\cross{MTSCAT}{cosh} &
+\cross{MTSCAT}{cot} &
+\cross{MTSCAT}{coth} &
+\cross{MTSCAT}{csc} \\
+\cross{MTSCAT}{csch} &
+\cross{MTSCAT}{D} &
+\cross{MTSCAT}{degree} &
+\cross{MTSCAT}{differentiate} &
+\cross{MTSCAT}{eval} \\
+\cross{MTSCAT}{exp} &
+\cross{MTSCAT}{exquo} &
+\cross{MTSCAT}{extend} &
+\cross{MTSCAT}{hash} &
+\cross{MTSCAT}{integrate} \\
+\cross{MTSCAT}{latex} &
+\cross{MTSCAT}{leadingCoefficient} &
+\cross{MTSCAT}{leadingMonomial} &
+\cross{MTSCAT}{log} &
+\cross{MTSCAT}{map} \\
+\cross{MTSCAT}{monomial} &
+\cross{MTSCAT}{monomial?} &
+\cross{MTSCAT}{nthRoot} &
+\cross{MTSCAT}{order} &
+\cross{MTSCAT}{one?} \\
+\cross{MTSCAT}{pi} &
+\cross{MTSCAT}{pole?} &
+\cross{MTSCAT}{polynomial} &
+\cross{MTSCAT}{recip} &
+\cross{MTSCAT}{reductum} \\
+\cross{MTSCAT}{sample} &
+\cross{MTSCAT}{sec} &
+\cross{MTSCAT}{sech} &
+\cross{MTSCAT}{sin} &
+\cross{MTSCAT}{sinh} \\
+\cross{MTSCAT}{sqrt} &
+\cross{MTSCAT}{subtractIfCan} &
+\cross{MTSCAT}{tan} &
+\cross{MTSCAT}{tanh} &
+\cross{MTSCAT}{unit?} \\
+\cross{MTSCAT}{unitCanonical} &
+\cross{MTSCAT}{unitNormal} &
+\cross{MTSCAT}{variables} &
+\cross{MTSCAT}{zero?} &
+\cross{MTSCAT}{?*?} \\
+\cross{MTSCAT}{?**?} &
+\cross{MTSCAT}{?+?} &
+\cross{MTSCAT}{?-?} &
+\cross{MTSCAT}{-?} &
+\cross{MTSCAT}{?=?} \\
+\cross{MTSCAT}{?\^{}?} &
+\cross{MTSCAT}{?\~{}=?} &
+\cross{MTSCAT}{?/?} &&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item if \$ has CommutativeRing then commutative(``*'') where
+{\bf \cross{MTSCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\item if \$ has IntegralDomain then noZeroDivisors where
+{\bf \cross{MTSCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{MTSCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{MTSCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{MTSCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ coefficient : (%,Var,NonNegativeInteger) -> %
+ coefficient : (%,List Var,List NonNegativeInteger) -> %
+ extend : (%,NonNegativeInteger) -> %
+ integrate : (%,Var) -> % if Coef has ALGEBRA FRAC INT
+ monomial : (%,Var,NonNegativeInteger) -> %
+ monomial : (%,List Var,List NonNegativeInteger) -> %
+ order : (%,Var,NonNegativeInteger) -> NonNegativeInteger
+ order : (%,Var) -> NonNegativeInteger
+ polynomial : (%,NonNegativeInteger,NonNegativeInteger) -> Polynomial Coef
+ polynomial : (%,NonNegativeInteger) -> Polynomial Coef
+\end{verbatim}
+
+These exports come from \refto{PartialDifferentialRing}(OrderedSet):
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ characteristic : () -> NonNegativeInteger
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ D : (%,Var) -> %
+ D : (%,List Var) -> %                
+ D : (%,List Var,List NonNegativeInteger) -> %
+ D : (%,Var,NonNegativeInteger) -> %
+ differentiate : (%,Var) -> %         
+ differentiate : (%,List Var,List NonNegativeInteger) -> %
+ differentiate : (%,Var,NonNegativeInteger) -> %
+ differentiate : (%,List Var) -> %
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ one? : % -> Boolean
+ recip : % -> Union(%,"failed")
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (%,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (NonNegativeInteger,%) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?^? : (%,PositiveInteger) -> %       
+ ?^? : (%,NonNegativeInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from \refto{PowerSeriesCategory}(A,B,C)\\
+where A:Ring, B:IndexedExponents(OrderedSet) and C:OrderedSet:
+\begin{verbatim}
+ associates? : (%,%) -> Boolean if Coef has INTDOM
+ charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
+ coefficient : (%,IndexedExponents Var) -> Coef
+ coerce : Coef -> % if Coef has COMRING
+ coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
+ coerce : % -> % if Coef has INTDOM
+ complete : % -> %
+ degree : % -> IndexedExponents Var
+ exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ leadingCoefficient : % -> Coef
+ leadingMonomial : % -> %             
+ map : ((Coef -> Coef),%) -> %
+ monomial : (Coef,IndexedExponents Var) -> %
+ monomial? : % -> Boolean             
+ monomial : (%,List Var,List IndexedExponents Var) -> %
+ monomial : (%,Var,IndexedExponents Var) -> %
+ pole? : % -> Boolean                 
+ reductum : % -> %                    
+ unit? : % -> Boolean if Coef has INTDOM
+ unitCanonical : % -> % if Coef has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
+   if Coef has INTDOM
+ variables : % -> List Var            
+ ?*? : (%,Coef) -> %                  
+ ?*? : (Coef,%) -> %
+ ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
+ ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?/? : (%,Coef) -> % if Coef has FIELD
+\end{verbatim}
+
+These exports come from \refto{InnerEvalable}(OrderedSet,%):
+\begin{verbatim}
+ eval : (%,Var,%) -> %                
+ eval : (%,List Var,List %) -> %
+\end{verbatim}
+
+These exports come from \refto{Evalable}(%):
+\begin{verbatim}
+ eval : (%,List Equation %) -> %      
+ eval : (%,Equation %) -> %
+ eval : (%,List %,List %) -> %
+ eval : (%,%,%) -> %                  
+\end{verbatim}
+
+These exports come from \refto{RadicalCategory}():
+\begin{verbatim}
+ nthRoot : (%,Integer) -> % if Coef has ALGEBRA FRAC INT
+ sqrt : % -> % if Coef has ALGEBRA FRAC INT
+ ?**? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+\end{verbatim}
+
+These exports come from \refto{TranscendentalFunctionCategory}():
+\begin{verbatim}
+ acos : % -> % if Coef has ALGEBRA FRAC INT
+ acosh : % -> % if Coef has ALGEBRA FRAC INT
+ acot : % -> % if Coef has ALGEBRA FRAC INT
+ acoth : % -> % if Coef has ALGEBRA FRAC INT
+ acsc : % -> % if Coef has ALGEBRA FRAC INT
+ acsch : % -> % if Coef has ALGEBRA FRAC INT
+ asec : % -> % if Coef has ALGEBRA FRAC INT
+ asech : % -> % if Coef has ALGEBRA FRAC INT
+ asin : % -> % if Coef has ALGEBRA FRAC INT
+ asinh : % -> % if Coef has ALGEBRA FRAC INT
+ atan : % -> % if Coef has ALGEBRA FRAC INT
+ atanh : % -> % if Coef has ALGEBRA FRAC INT
+ cos : % -> % if Coef has ALGEBRA FRAC INT
+ cosh : % -> % if Coef has ALGEBRA FRAC INT
+ cot : % -> % if Coef has ALGEBRA FRAC INT
+ coth : % -> % if Coef has ALGEBRA FRAC INT
+ csc : % -> % if Coef has ALGEBRA FRAC INT
+ csch : % -> % if Coef has ALGEBRA FRAC INT
+ exp : % -> % if Coef has ALGEBRA FRAC INT
+ log : % -> % if Coef has ALGEBRA FRAC INT
+ pi : () -> % if Coef has ALGEBRA FRAC INT
+ sec : % -> % if Coef has ALGEBRA FRAC INT
+ sech : % -> % if Coef has ALGEBRA FRAC INT
+ sin : % -> % if Coef has ALGEBRA FRAC INT
+ sinh : % -> % if Coef has ALGEBRA FRAC INT
+ tan : % -> % if Coef has ALGEBRA FRAC INT
+ tanh : % -> % if Coef has ALGEBRA FRAC INT
+ ?**? : (%,%) -> % if Coef has ALGEBRA FRAC INT
+\end{verbatim}
+
+<<category MTSCAT MultivariateTaylorSeriesCategory>>=
+)abbrev category MTSCAT MultivariateTaylorSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 6 March 1990
+++ Date Last Updated: 6 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: multivariate, Taylor, series
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{MultivariateTaylorSeriesCategory} is the most general
+++   multivariate Taylor series category.
+MultivariateTaylorSeriesCategory(Coef,Var): Category == Definition where
+  Coef  : Ring
+  Var   : OrderedSet
+  L   ==> List
+  NNI ==> NonNegativeInteger
+
+  Definition ==> Join(PartialDifferentialRing Var,_
+                     PowerSeriesCategory(Coef,IndexedExponents Var,Var),_
+                     InnerEvalable(Var,%),Evalable %) with
+    coefficient: (%,Var,NNI) -> %
+      ++ \spad{coefficient(f,x,n)} returns the coefficient of \spad{x^n} in f.
+    coefficient: (%,L Var,L NNI) -> %
+      ++ \spad{coefficient(f,[x1,x2,...,xk],[n1,n2,...,nk])} returns the
+      ++ coefficient of \spad{x1^n1 * ... * xk^nk} in f.
+    extend: (%,NNI) -> %
+      ++ \spad{extend(f,n)} causes all terms of f of degree
+      ++ \spad{<= n} to be computed.
+    monomial: (%,Var,NNI) -> %
+      ++ \spad{monomial(a,x,n)} returns  \spad{a*x^n}.
+    monomial: (%,L Var,L NNI) -> %
+      ++ \spad{monomial(a,[x1,x2,...,xk],[n1,n2,...,nk])} returns
+      ++ \spad{a * x1^n1 * ... * xk^nk}.
+    order: (%,Var) -> NNI
+      ++ \spad{order(f,x)} returns the order of f viewed as a series in x
+      ++ may result in an infinite loop if f has no non-zero terms.
+    order: (%,Var,NNI) -> NNI
+      ++ \spad{order(f,x,n)} returns \spad{min(n,order(f,x))}.
+    polynomial: (%,NNI) -> Polynomial Coef
+      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
+      ++ of all terms of f of degree \spad{<= k}.
+    polynomial: (%,NNI,NNI) -> Polynomial Coef
+      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
+      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+    if Coef has Algebra Fraction Integer then
+      integrate: (%,Var) -> %
+        ++ \spad{integrate(f,x)} returns the anti-derivative of the power
+        ++ series \spad{f(x)} with respect to the variable x with constant
+        ++ coefficient 1.  We may integrate a series when we can divide
+        ++ coefficients by integers.
+      RadicalCategory
+        --++ We provide rational powers when we can divide coefficients
+        --++ by integers.
+      TranscendentalFunctionCategory
+        --++ We provide transcendental functions when we can divide
+        --++ coefficients by integers.
+
+@
+<<MTSCAT.dotabb>>=
+"MTSCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MTSCAT"];
+"MTSCAT" -> "PDRING"
+"MTSCAT" -> "PSCAT"
+"MTSCAT" -> "IEVALAB"
+"MTSCAT" -> "EVALAB"
+
+@
+<<MTSCAT.dotfull>>=
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MTSCAT"];
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+    "PartialDifferentialRing(a:OrderedSet)"
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+   "PowerSeriesCategory(a:Ring,IndexedExponents(b:OrderedSet),c:OrderedSet))"
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+ "InnerEvalable(a:Ring,MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet))"
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+ "Evalable(MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet))"
+
+@
+<<MTSCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" [color=lightblue];
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+    "PDRING..."
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+   "PSCAT..."
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+ "IEVALAB..."
+"MultivariateTaylorSeriesCategory(a:Ring,b:OrderedSet)" ->
+ "EVALAB..."
+
+"PDRING..." [color=lightblue];
+"PSCAT..." [color=lightblue];
+"IEVALAB..." [color=lightblue];
+"EVALAB..." [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{PolynomialFactorizationExplicit}{PFECAT}
 \pagepic{ps/v102polynomialfactorizationexplicit.ps}{PFECAT}{0.80}
 
@@ -37732,7 +39957,412 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 16}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{UnivariatePowerSeriesCategory}{UPSCAT}
+\pagepic{ps/v102univariatepowerseriescategory.ps}{UPSCAT}{0.55}
+
+{\bf See:}\\
+\pageto{UnivariateLaurentSeriesCategory}{ULSCAT}
+\pageto{UnivariatePuiseuxSeriesCategory}{UPXSCAT}
+\pageto{UnivariateTaylorSeriesCategory}{UTSCAT}
+\pagefrom{PowerSeriesCategory}{PSCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{UPSCAT}{0} &
+\cross{UPSCAT}{1} &
+\cross{UPSCAT}{approximate} &
+\cross{UPSCAT}{associates?} &
+\cross{UPSCAT}{center} \\
+\cross{UPSCAT}{characteristic} &
+\cross{UPSCAT}{charthRoot} &
+\cross{UPSCAT}{coefficient} &
+\cross{UPSCAT}{coerce} &
+\cross{UPSCAT}{complete} \\
+\cross{UPSCAT}{D} &
+\cross{UPSCAT}{degree} &
+\cross{UPSCAT}{differentiate} &
+\cross{UPSCAT}{eval} &
+\cross{UPSCAT}{exquo} \\
+\cross{UPSCAT}{extend} &
+\cross{UPSCAT}{hash} &
+\cross{UPSCAT}{latex} &
+\cross{UPSCAT}{leadingCoefficient} &
+\cross{UPSCAT}{leadingMonomial} \\
+\cross{UPSCAT}{map} &
+\cross{UPSCAT}{monomial} &
+\cross{UPSCAT}{monomial?} &
+\cross{UPSCAT}{multiplyExponents} &
+\cross{UPSCAT}{one?} \\
+\cross{UPSCAT}{order} &
+\cross{UPSCAT}{pole?} &
+\cross{UPSCAT}{recip} &
+\cross{UPSCAT}{reductum} &
+\cross{UPSCAT}{sample} \\
+\cross{UPSCAT}{subtractIfCan} &
+\cross{UPSCAT}{truncate} &
+\cross{UPSCAT}{terms} &
+\cross{UPSCAT}{unit?} &
+\cross{UPSCAT}{unitCanonical} \\
+\cross{UPSCAT}{unitNormal} &
+\cross{UPSCAT}{variable} &
+\cross{UPSCAT}{variables} &
+\cross{UPSCAT}{zero?} &
+\cross{UPSCAT}{?*?} \\
+\cross{UPSCAT}{?**?} &
+\cross{UPSCAT}{?+?} &
+\cross{UPSCAT}{?-?} &
+\cross{UPSCAT}{-?} &
+\cross{UPSCAT}{?=?} \\
+\cross{UPSCAT}{?\^{}?} &
+\cross{UPSCAT}{?.?} &
+\cross{UPSCAT}{?\~{}=?} &
+\cross{UPSCAT}{?/?} &
+\cross{UPSCAT}{?.?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{UPSCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{UPSCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{UPSCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item if \#1 has IntegralDomain then noZeroDivisors where
+{\bf \cross{UPSCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item if \#1 has CommutativeRing then commutative(``*'') where
+{\bf \cross{UPSCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ approximate : (%,Expon) -> Coef 
+     if Coef has **: (Coef,Expon) -> Coef 
+     and Coef has coerce: Symbol -> Coef
+ center : % -> Coef
+ eval : (%,Coef) -> Stream Coef if Coef has **: (Coef,Expon) -> Coef
+ extend : (%,Expon) -> %              
+ multiplyExponents : (%,PositiveInteger) -> %
+ order : % -> Expon                   
+ order : (%,Expon) -> Expon
+ terms : % -> Stream Record(k: Expon,c: Coef)
+ truncate : (%,Expon) -> %            
+ truncate : (%,Expon,Expon) -> %
+ variable : % -> Symbol
+ ?.? : (%,Expon) -> Coef
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ degree : % -> Expon                  
+ leadingCoefficient : % -> Coef
+ leadingMonomial : % -> %             
+ monomial : (%,SingletonAsOrderedSet,Expon) -> %
+ reductum : % -> %
+ variables : % -> List SingletonAsOrderedSet
+\end{verbatim}
+
+These exports come from \refto{PowerSeriesCategory}(C,E,S)\\
+where C:Ring, E:OrderedAbelianMonoid, S:SingletonAsOrderedSet:\\
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ associates? : (%,%) -> Boolean if Coef has INTDOM
+ characteristic : () -> NonNegativeInteger
+ charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
+ coefficient : (%,Expon) -> Coef      
+ coerce : Coef -> % if Coef has COMRING
+ coerce : % -> % if Coef has INTDOM
+ coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ complete : % -> %
+ exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ map : ((Coef -> Coef),%) -> %
+ monomial : (%,List Var,List Expon) -> %
+ monomial : (Coef,Expon) -> %         
+ monomial? : % -> Boolean
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")       
+ pole? : % -> Boolean
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ unit? : % -> Boolean if Coef has INTDOM
+ unitCanonical : % -> % if Coef has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
+     if Coef has INTDOM
+ zero? : % -> Boolean                 
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (Coef,%) -> %                  
+ ?*? : (%,Coef) -> %
+ ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
+ ?/? : (%,Coef) -> % if Coef has FIELD
+ -? : % -> %                          
+\end{verbatim}
+
+These exports come from \refto{Eltable}(\%,\%):
+\begin{verbatim}
+ ?.? : (%,%) -> % if Expon has SGROUP
+\end{verbatim}
+
+These exports come from \refto{DifferentialRing}():
+\begin{verbatim}
+ D : % -> % 
+     if Coef has *: (Expon,Coef) -> Coef
+ D : (%,NonNegativeInteger) -> % 
+     if Coef has *: (Expon,Coef) -> Coef
+ differentiate : (%,NonNegativeInteger) -> % 
+     if Coef has *: (Expon,Coef) -> Coef
+ differentiate : % -> % 
+     if Coef has *: (Expon,Coef) -> Coef
+\end{verbatim}
+
+These exports come from \refto{PartialDifferentialRing}(Symbol):
+\begin{verbatim}
+ D : (%,Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ D : (%,List Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ D : (%,Symbol,NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ D : (%,List Symbol,List NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ differentiate : (%,List Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ differentiate : (%,Symbol,NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+ differentiate : (%,Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (Expon,Coef) -> Coef
+\end{verbatim}
+
+<<category UPSCAT UnivariatePowerSeriesCategory>>=
+)abbrev category UPSCAT UnivariatePowerSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 20 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{UnivariatePowerSeriesCategory} is the most general
+++   univariate power series category with exponents in an ordered
+++   abelian monoid.
+++   Note: this category exports a substitution function if it is
+++   possible to multiply exponents.
+++   Note: this category exports a derivative operation if it is possible
+++   to multiply coefficients by exponents.
+UnivariatePowerSeriesCategory(Coef,Expon): Category == Definition where
+  Coef   : Ring
+  Expon  : OrderedAbelianMonoid
+  Term ==> Record(k:Expon,c:Coef)
+
+  Definition ==> PowerSeriesCategory(Coef,Expon,SingletonAsOrderedSet) with
+
+    terms: % -> Stream Term
+      ++ \spad{terms(f(x))} returns a stream of non-zero terms, where a
+      ++ a term is an exponent-coefficient pair.  The terms in the stream
+      ++ are ordered by increasing order of exponents.
+    --series: Stream Term -> %
+      --++ \spad{series(st)} creates a series from a stream of non-zero terms,
+      --++ where a term is an exponent-coefficient pair.  The terms in the
+      --++ stream should be ordered by increasing order of exponents.
+    elt: (%,Expon) -> Coef
+      ++ \spad{elt(f(x),r)} returns the coefficient of the term of degree r in
+      ++ \spad{f(x)}.  This is the same as the function \spadfun{coefficient}.
+    variable: % -> Symbol
+      ++ \spad{variable(f)} returns the (unique) power series variable of
+      ++ the power series f.
+    center: % -> Coef
+      ++ \spad{center(f)} returns the point about which the series f is
+      ++ expanded.
+    multiplyExponents: (%,PositiveInteger) -> %
+      ++ \spad{multiplyExponents(f,n)} multiplies all exponents of the power
+      ++ series f by the positive integer n.
+    order: % -> Expon
+      ++ \spad{order(f)} is the degree of the lowest order non-zero term in f.
+      ++ This will result in an infinite loop if f has no non-zero terms.
+    order: (%,Expon) -> Expon
+      ++ \spad{order(f,n) = min(m,n)}, where m is the degree of the
+      ++ lowest order non-zero term in f.
+    truncate: (%,Expon) -> %
+      ++ \spad{truncate(f,k)} returns a (finite) power series consisting of
+      ++ the sum of all terms of f of degree \spad{<= k}.
+    truncate: (%,Expon,Expon) -> %
+      ++ \spad{truncate(f,k1,k2)} returns a (finite) power
+      ++ series consisting of
+      ++ the sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+    if Coef has coerce: Symbol -> Coef then
+      if Coef has "**":(Coef,Expon) -> Coef then
+        approximate: (%,Expon) -> Coef
+          ++ \spad{approximate(f)} returns a truncated power series with the
+          ++ series variable viewed as an element of the coefficient domain.
+    extend: (%,Expon) -> %
+      ++ \spad{extend(f,n)} causes all terms of f of degree <= n 
+      ++ to be computed.
+    if Expon has SemiGroup then Eltable(%,%)
+    if Coef has "*": (Expon,Coef) -> Coef then
+      DifferentialRing
+      --!! DifferentialExtension Coef
+      if Coef has PartialDifferentialRing Symbol then
+        PartialDifferentialRing Symbol
+    if Coef has "**": (Coef,Expon) -> Coef then
+      eval: (%,Coef) -> Stream Coef
+        ++ \spad{eval(f,a)} evaluates a power series at a value in the
+        ++ ground ring by returning a stream of partial sums.
+
+   add
+    degree f == order f
+
+    leadingCoefficient f == coefficient(f,order f)
+
+    leadingMonomial f ==
+      ord := order f
+      monomial(coefficient(f,ord),ord)
+
+    monomial(f:%,listVar:List SingletonAsOrderedSet,listExpon:List Expon) ==
+      empty? listVar or not empty? rest listVar =>
+        error "monomial: variable list must have exactly one entry"
+      empty? listExpon or not empty? rest listExpon =>
+        error "monomial: exponent list must have exactly one entry"
+      f * monomial(1,first listExpon)
+
+    monomial(f:%,v:SingletonAsOrderedSet,n:Expon) ==
+      f * monomial(1,n)
+
+    reductum f == f - leadingMonomial f
+
+    variables f == list create()
+
+@
+<<UPSCAT.dotabb>>=
+"UPSCAT" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UPSCAT" -> "PSCAT"
+
+@
+<<UPSCAT.dotfull>>=
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
+ "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+
+"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" -> 
+    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+
+"UnivariatePowerSeriesCategory(a:Ring,Integer)" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UnivariatePowerSeriesCategory(a:Ring,Integer)" -> 
+    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+
+"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" ->
+    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+
+@
+<<UPSCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
+ [color=lightblue];
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
+ "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+ [color=seagreen];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+ [color=lightblue];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BIMODULE..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+"IntegralDomain()" [color=lightblue];
+"IntegralDomain()" -> "CommutativeRing()"
+"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
+"IntegralDomain()" -> "EntireRing()"
+
+"EntireRing()" [color=lightblue];
+"EntireRing()" -> "RING..."
+"EntireRing()" -> "BIMODULE..."
+
+"CharacteristicNonZero()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
+"CharacteristicNonZero()" -> "RING..."
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "RING..."
+"Algebra(a:CommutativeRing)" -> "MODULE..."
+
+"CommutativeRing()" [color=lightblue];
+"CommutativeRing()" -> "RING..."
+"CommutativeRing()" -> "BIMODULE..."
+
+"BIMODULE..." [color=lightblue];
+"RING..." [color=lightblue];
+"MODULE..." [color=lightblue];
+}
+
+@
+\chapter{Category Layer 15}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{Field}{FIELD}
 \pagepic{ps/v102field.ps}{FIELD}{1.00}
@@ -37744,6 +40374,7 @@ digraph pic {
 \pageto{FiniteRankAlgebra}{FINRALG}
 \pageto{FunctionSpace}{FS}
 \pageto{QuotientFieldCategory}{QFCAT}
+\pageto{RealClosedField}{RCFIELD}
 \pageto{RealNumberSystem}{RNS}
 \pageto{UnivariateLaurentSeriesCategory}{ULSCAT}
 \pageto{UnivariatePolynomialCategory}{UPOLYC}
@@ -39669,7 +42300,658 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 17}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{UnivariateTaylorSeriesCategory}{UTSCAT}
+\pagepic{ps/v102univariatetaylorseriescategory.ps}{UTSCAT}{0.60}
+
+{\bf See:}\\
+\pagefrom{RadicalCategory}{RADCAT}
+\pagefrom{TranscendentalFunctionCategory}{TRANFUN}
+\pagefrom{UnivariatePowerSeriesCategory}{UPSCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{UTSCAT}{0} &
+\cross{UTSCAT}{1} &
+\cross{UTSCAT}{acos} &
+\cross{UTSCAT}{acosh} \\
+\cross{UTSCAT}{acot} &
+\cross{UTSCAT}{acoth} &
+\cross{UTSCAT}{acsc} &
+\cross{UTSCAT}{acsch} \\
+\cross{UTSCAT}{approximate} &
+\cross{UTSCAT}{asec} &
+\cross{UTSCAT}{asech} &
+\cross{UTSCAT}{asin} \\
+\cross{UTSCAT}{asinh} &
+\cross{UTSCAT}{associates?} &
+\cross{UTSCAT}{atan} &
+\cross{UTSCAT}{atanh} \\
+\cross{UTSCAT}{center} &
+\cross{UTSCAT}{characteristic} &
+\cross{UTSCAT}{charthRoot} &
+\cross{UTSCAT}{coefficient} \\
+\cross{UTSCAT}{coefficients} &
+\cross{UTSCAT}{coerce} &
+\cross{UTSCAT}{complete} &
+\cross{UTSCAT}{cos} \\
+\cross{UTSCAT}{cosh} &
+\cross{UTSCAT}{cot} &
+\cross{UTSCAT}{coth} &
+\cross{UTSCAT}{csc} \\
+\cross{UTSCAT}{csch} &
+\cross{UTSCAT}{D} &
+\cross{UTSCAT}{degree} &
+\cross{UTSCAT}{differentiate} \\
+\cross{UTSCAT}{eval} &
+\cross{UTSCAT}{exp} &
+\cross{UTSCAT}{exquo} &
+\cross{UTSCAT}{extend} \\
+\cross{UTSCAT}{hash} &
+\cross{UTSCAT}{integrate} &
+\cross{UTSCAT}{latex} &
+\cross{UTSCAT}{leadingCoefficient} \\
+\cross{UTSCAT}{leadingMonomial} &
+\cross{UTSCAT}{log} &
+\cross{UTSCAT}{map} &
+\cross{UTSCAT}{monomial} \\
+\cross{UTSCAT}{monomial?} &
+\cross{UTSCAT}{multiplyCoefficients} &
+\cross{UTSCAT}{multiplyExponents} &
+\cross{UTSCAT}{nthRoot} \\
+\cross{UTSCAT}{one?} &
+\cross{UTSCAT}{order} &
+\cross{UTSCAT}{pi} &
+\cross{UTSCAT}{pole?} \\
+\cross{UTSCAT}{polynomial} &
+\cross{UTSCAT}{quoByVar} &
+\cross{UTSCAT}{recip} &
+\cross{UTSCAT}{reductum} \\
+\cross{UTSCAT}{sample} &
+\cross{UTSCAT}{sec} &
+\cross{UTSCAT}{sech} &
+\cross{UTSCAT}{series} \\
+\cross{UTSCAT}{sin} &
+\cross{UTSCAT}{sinh} &
+\cross{UTSCAT}{sqrt} &
+\cross{UTSCAT}{subtractIfCan} \\
+\cross{UTSCAT}{tan} &
+\cross{UTSCAT}{tanh} &
+\cross{UTSCAT}{terms} &
+\cross{UTSCAT}{truncate} \\
+\cross{UTSCAT}{unit?} &
+\cross{UTSCAT}{unitCanonical} &
+\cross{UTSCAT}{unitNormal} &
+\cross{UTSCAT}{variable} \\
+\cross{UTSCAT}{variables} &
+\cross{UTSCAT}{zero?} &
+\cross{UTSCAT}{?*?} &
+\cross{UTSCAT}{?**?} \\
+\cross{UTSCAT}{?+?} &
+\cross{UTSCAT}{?-?} &
+\cross{UTSCAT}{-?} &
+\cross{UTSCAT}{?=?} \\
+\cross{UTSCAT}{?\^{}?} &
+\cross{UTSCAT}{?\~{}=?} &
+\cross{UTSCAT}{?/?} &
+\cross{UTSCAT}{?.?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{UTSCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{UTSCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{UTSCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item if \#1 has IntegralDomain then noZeroDivisors where
+{\bf \cross{UTSCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item if \#1 has CommutativeRing then commutative(``*'') where
+{\bf \cross{UTSCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ coefficients : % -> Stream Coef      
+ integrate : (%,Symbol) -> % 
+     if Coef has ACFS INT 
+     and Coef has PRIMCAT 
+     and Coef has TRANFUN 
+     and Coef has ALGEBRA FRAC INT 
+     or Coef has variables: Coef -> List Symbol 
+     and Coef has integrate: (Coef,Symbol) -> Coef 
+     and Coef has ALGEBRA FRAC INT
+ integrate : % -> % if Coef has ALGEBRA FRAC INT
+ multiplyCoefficients : ((Integer -> Coef),%) -> %
+ polynomial : (%,NonNegativeInteger,NonNegativeInteger) -> Polynomial Coef
+ polynomial : (%,NonNegativeInteger) -> Polynomial Coef
+ quoByVar : % -> %                    
+ series : Stream Coef -> %            
+ series : Stream Record(k: NonNegativeInteger,c: Coef) -> %
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ acos : % -> % if Coef has ALGEBRA FRAC INT
+ acosh : % -> % if Coef has ALGEBRA FRAC INT
+ acot : % -> % if Coef has ALGEBRA FRAC INT
+ acoth : % -> % if Coef has ALGEBRA FRAC INT
+ acsc : % -> % if Coef has ALGEBRA FRAC INT
+ acsch : % -> % if Coef has ALGEBRA FRAC INT
+ asec : % -> % if Coef has ALGEBRA FRAC INT
+ asech : % -> % if Coef has ALGEBRA FRAC INT
+ asin : % -> % if Coef has ALGEBRA FRAC INT
+ asinh : % -> % if Coef has ALGEBRA FRAC INT
+ atan : % -> % if Coef has ALGEBRA FRAC INT
+ atanh : % -> % if Coef has ALGEBRA FRAC INT
+ coerce : % -> OutputForm             
+ cos : % -> % if Coef has ALGEBRA FRAC INT
+ cosh : % -> % if Coef has ALGEBRA FRAC INT
+ cot : % -> % if Coef has ALGEBRA FRAC INT
+ coth : % -> % if Coef has ALGEBRA FRAC INT
+ csc : % -> % if Coef has ALGEBRA FRAC INT
+ csch : % -> % if Coef has ALGEBRA FRAC INT
+ exp : % -> % if Coef has ALGEBRA FRAC INT
+ log : % -> % if Coef has ALGEBRA FRAC INT
+ sinh : % -> % if Coef has ALGEBRA FRAC INT
+ sec : % -> % if Coef has ALGEBRA FRAC INT
+ sech : % -> % if Coef has ALGEBRA FRAC INT
+ sin : % -> % if Coef has ALGEBRA FRAC INT
+ tan : % -> % if Coef has ALGEBRA FRAC INT
+ tanh : % -> % if Coef has ALGEBRA FRAC INT
+ zero? : % -> Boolean                 
+ ?**? : (%,Coef) -> % if Coef has FIELD
+ ?**? : (%,%) -> % if Coef has ALGEBRA FRAC INT
+ ?**? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+\end{verbatim}
+
+These exports come from \refto{UnivariatePowerSeriesCategory}(Coef,NNI)\\
+where Coef:Ring and NNI:NonNegativeInteger:
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ approximate : (%,NonNegativeInteger) -> Coef 
+     if Coef has **: (Coef,NonNegativeInteger) -> Coef 
+     and Coef has coerce: Symbol -> Coef
+ associates? : (%,%) -> Boolean if Coef has INTDOM
+ center : % -> Coef
+ characteristic : () -> NonNegativeInteger
+ charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
+ coefficient : (%,NonNegativeInteger) -> Coef
+ coerce : Coef -> % if Coef has COMRING
+ coerce : % -> % if Coef has INTDOM
+ coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
+ coerce : Integer -> %
+ complete : % -> %
+ D : % -> % if Coef has *: (NonNegativeInteger,Coef) -> Coef
+ D : (%,NonNegativeInteger) -> % 
+     if Coef has *: (NonNegativeInteger,Coef) -> Coef
+ D : (%,Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ D : (%,List Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ D : (%,Symbol,NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ D : (%,List Symbol,List NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : (%,List Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : (%,Symbol,NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : (%,Symbol) -> % 
+     if Coef has PDRING SYMBOL 
+     and Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : (%,NonNegativeInteger) -> % 
+     if Coef has *: (NonNegativeInteger,Coef) -> Coef
+ differentiate : % -> % 
+     if Coef has *: (NonNegativeInteger,Coef) -> Coef
+ degree : % -> NonNegativeInteger     
+ extend : (%,NonNegativeInteger) -> %
+ exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ eval : (%,Coef) -> Stream Coef 
+     if Coef has **: (Coef,NonNegativeInteger) -> Coef
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ leadingCoefficient : % -> Coef
+ leadingMonomial : % -> %             
+ map : ((Coef -> Coef),%) -> %
+ monomial : (Coef,NonNegativeInteger) -> %
+ monomial : (%,SingletonAsOrderedSet,NonNegativeInteger) -> %
+ monomial : (%,List SingletonAsOrderedSet,List NonNegativeInteger) -> %
+ monomial? : % -> Boolean             
+ multiplyExponents : (%,PositiveInteger) -> %
+ one? : % -> Boolean
+ order : % -> NonNegativeInteger      
+ order : (%,NonNegativeInteger) -> NonNegativeInteger
+ pole? : % -> Boolean
+ recip : % -> Union(%,"failed")
+ reductum : % -> %                    
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ terms : % -> Stream Record(k: NonNegativeInteger,c: Coef)
+ truncate : (%,NonNegativeInteger,NonNegativeInteger) -> %
+ truncate : (%,NonNegativeInteger) -> %
+ unit? : % -> Boolean if Coef has INTDOM
+ unitCanonical : % -> % if Coef has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
+     if Coef has INTDOM
+ variable : % -> Symbol
+ variables : % -> List SingletonAsOrderedSet
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (Coef,%) -> %                  
+ ?*? : (%,Coef) -> %
+ ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
+ ?/? : (%,Coef) -> % if Coef has FIELD
+ -? : % -> %                          
+ ?.? : (%,%) -> % if NonNegativeInteger has SGROUP
+ ?.? : (%,NonNegativeInteger) -> Coef
+\end{verbatim}
+
+These exports come from \refto{TranscendentalFunctionCategory}():
+\begin{verbatim}
+ pi : () -> % if Coef has ALGEBRA FRAC INT
+\end{verbatim}
+
+These exports come from \refto{RadicalCategory}():
+\begin{verbatim}
+ nthRoot : (%,Integer) -> % if Coef has ALGEBRA FRAC INT
+ sqrt : % -> % if Coef has ALGEBRA FRAC INT
+\end{verbatim}
+
+<<category UTSCAT UnivariateTaylorSeriesCategory>>=
+)abbrev category UTSCAT UnivariateTaylorSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 26 May 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Taylor, linebacker
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{UnivariateTaylorSeriesCategory} is the category of Taylor
+++   series in one variable.
+UnivariateTaylorSeriesCategory(Coef): Category == Definition where
+  Coef  : Ring
+  I    ==> Integer
+  L    ==> List
+  NNI  ==> NonNegativeInteger
+  OUT  ==> OutputForm
+  RN   ==> Fraction Integer
+  STTA ==> StreamTaylorSeriesOperations Coef
+  STTF ==> StreamTranscendentalFunctions Coef
+  STNC ==> StreamTranscendentalFunctionsNonCommutative Coef
+  Term ==> Record(k:NNI,c:Coef)
+
+  Definition ==> UnivariatePowerSeriesCategory(Coef,NNI) with
+
+    series: Stream Term -> %
+      ++ \spad{series(st)} creates a series from a stream of non-zero terms,
+      ++ where a term is an exponent-coefficient pair.  The terms in the
+      ++ stream should be ordered by increasing order of exponents.
+    coefficients: % -> Stream Coef
+      ++ \spad{coefficients(a0 + a1 x + a2 x**2 + ...)} returns a stream
+      ++ of coefficients: \spad{[a0,a1,a2,...]}. The entries of the stream
+      ++ may be zero.
+    series: Stream Coef -> %
+      ++ \spad{series([a0,a1,a2,...])} is the Taylor series
+      ++ \spad{a0 + a1 x + a2 x**2 + ...}.
+    quoByVar: % -> %
+      ++ \spad{quoByVar(a0 + a1 x + a2 x**2 + ...)}
+      ++ returns \spad{a1 + a2 x + a3 x**2 + ...}
+      ++ Thus, this function substracts the constant term and divides by
+      ++ the series variable.  This function is used when Laurent series
+      ++ are represented by a Taylor series and an order.
+    multiplyCoefficients: (I -> Coef,%) -> %
+      ++ \spad{multiplyCoefficients(f,sum(n = 0..infinity,a[n] * x**n))}
+      ++ returns \spad{sum(n = 0..infinity,f(n) * a[n] * x**n)}.
+      ++ This function is used when Laurent series are represented by
+      ++ a Taylor series and an order.
+    polynomial: (%,NNI) -> Polynomial Coef
+      ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
+      ++ of all terms of f of degree \spad{<= k}.
+    polynomial: (%,NNI,NNI) -> Polynomial Coef
+      ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
+      ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+
+    if Coef has Field then
+      "**": (%,Coef) -> %
+        ++ \spad{f(x) ** a} computes a power of a power series.
+        ++ When the coefficient ring is a field, we may raise a series
+        ++ to an exponent from the coefficient ring provided that the
+        ++ constant coefficient of the series is 1.
+
+    if Coef has Algebra Fraction Integer then
+      integrate: % -> %
+        ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+        ++ series \spad{f(x)} with constant coefficient 0.
+        ++ We may integrate a series when we can divide coefficients
+        ++ by integers.
+      if Coef has integrate: (Coef,Symbol) -> Coef and _
+         Coef has variables: Coef -> List Symbol then
+        integrate: (%,Symbol) -> %
+          ++ \spad{integrate(f(x),y)} returns an anti-derivative of the
+          ++ power series \spad{f(x)} with respect to the variable \spad{y}.
+      if Coef has TranscendentalFunctionCategory and _
+         Coef has PrimitiveFunctionCategory and _
+         Coef has AlgebraicallyClosedFunctionSpace Integer then
+        integrate: (%,Symbol) -> %
+          ++ \spad{integrate(f(x),y)} returns an anti-derivative of
+          ++ the power series \spad{f(x)} with respect to the variable
+          ++ \spad{y}.
+      RadicalCategory
+        --++ We provide rational powers when we can divide coefficients
+        --++ by integers.
+      TranscendentalFunctionCategory
+        --++ We provide transcendental functions when we can divide
+        --++ coefficients by integers.
+
+   add
+
+    zero? x ==
+      empty? (coefs := coefficients x) => true
+      (zero? frst coefs) and (empty? rst coefs) => true
+      false
+
+--% OutputForms
+
+--  We provide defaulr output functions on UTSCAT using the functions
+--  'coefficients', 'center', and 'variable'.
+
+    factorials?: () -> Boolean
+    -- check a global Lisp variable
+    factorials?() == false
+
+    termOutput: (I,Coef,OUT) -> OUT
+    termOutput(k,c,vv) ==
+    -- creates a term c * vv ** k
+      k = 0 => c :: OUT
+      mon := (k = 1 => vv; vv ** (k :: OUT))
+--       if factorials?() and k > 1 then
+--         c := factorial(k)$IntegerCombinatoricFunctions * c
+--         mon := mon / hconcat(k :: OUT,"!" :: OUT)
+      c = 1 => mon
+      c = -1 => -mon
+      (c :: OUT) * mon
+
+    showAll?: () -> Boolean
+    -- check a global Lisp variable
+    showAll?() == true
+
+    coerce(p:%):OUT ==
+      empty? (uu := coefficients p) => (0$Coef) :: OUT
+      var := variable p; cen := center p
+      vv :=
+        zero? cen => var :: OUT
+        paren(var :: OUT - cen :: OUT)
+      n : NNI ; count : NNI := _$streamCount$Lisp
+      l : L OUT := empty()
+      for n in 0..count while not empty? uu repeat
+        if frst(uu) ^= 0 then
+          l := concat(termOutput(n :: I,frst uu,vv),l)
+        uu := rst uu
+      if showAll?() then
+        for n in (count + 1).. while explicitEntries? uu and _
+               not eq?(uu,rst uu) repeat
+          if frst(uu) ^= 0 then
+            l := concat(termOutput(n :: I,frst uu,vv),l)
+          uu := rst uu
+      l :=
+        explicitlyEmpty? uu => l
+        eq?(uu,rst uu) and frst uu = 0 => l
+        concat(prefix("O" :: OUT,[vv ** (n :: OUT)]),l)
+      empty? l => (0$Coef) :: OUT
+      reduce("+",reverse_! l)
+
+    if Coef has Field then
+      (x:%) ** (r:Coef) == series power(r,coefficients x)$STTA
+
+    if Coef has Algebra Fraction Integer then
+      if Coef has CommutativeRing then
+        (x:%) ** (y:%)    == series(coefficients x **$STTF coefficients y)
+
+        (x:%) ** (r:RN)   == series powern(r,coefficients x)$STTA
+
+        exp x == series exp(coefficients x)$STTF
+
+        log x == series log(coefficients x)$STTF
+
+        sin x == series sin(coefficients x)$STTF
+
+        cos x == series cos(coefficients x)$STTF
+
+        tan x == series tan(coefficients x)$STTF
+
+        cot x == series cot(coefficients x)$STTF
+
+        sec x == series sec(coefficients x)$STTF
+
+        csc x == series csc(coefficients x)$STTF
+
+        asin x == series asin(coefficients x)$STTF
+
+        acos x == series acos(coefficients x)$STTF
+
+        atan x == series atan(coefficients x)$STTF
+
+        acot x == series acot(coefficients x)$STTF
+
+        asec x == series asec(coefficients x)$STTF
+
+        acsc x == series acsc(coefficients x)$STTF
+
+        sinh x == series sinh(coefficients x)$STTF
+
+        cosh x == series cosh(coefficients x)$STTF
+
+        tanh x == series tanh(coefficients x)$STTF
+
+        coth x == series coth(coefficients x)$STTF
+
+        sech x == series sech(coefficients x)$STTF
+
+        csch x == series csch(coefficients x)$STTF
+
+        asinh x == series asinh(coefficients x)$STTF
+
+        acosh x == series acosh(coefficients x)$STTF
+
+        atanh x == series atanh(coefficients x)$STTF
+
+        acoth x == series acoth(coefficients x)$STTF
+
+        asech x == series asech(coefficients x)$STTF
+
+        acsch x == series acsch(coefficients x)$STTF
+
+      else
+        (x:%) ** (y:%) == series(coefficients x **$STNC coefficients y)
+
+        (x:%) ** (r:RN) ==
+          coefs := coefficients x
+          empty? coefs =>
+            positive? r => 0
+            zero? r => error "0**0 undefined"
+            error "0 raised to a negative power"
+--          not one? frst coefs =>
+          not (frst coefs = 1) =>
+            error "**: constant coefficient should be 1"
+          coefs := concat(0,rst coefs)
+          onePlusX := monom(1,0)$STTA + $STTA monom(1,1)$STTA
+          ratPow := powern(r,onePlusX)$STTA
+          series compose(ratPow,coefs)$STTA
+
+        exp x == series exp(coefficients x)$STNC
+
+        log x == series log(coefficients x)$STNC
+
+        sin x == series sin(coefficients x)$STNC
+
+        cos x == series cos(coefficients x)$STNC
+
+        tan x == series tan(coefficients x)$STNC
+
+        cot x == series cot(coefficients x)$STNC
+
+        sec x == series sec(coefficients x)$STNC
+
+        csc x == series csc(coefficients x)$STNC
+
+        asin x == series asin(coefficients x)$STNC
+
+        acos x == series acos(coefficients x)$STNC
+
+        atan x == series atan(coefficients x)$STNC
+
+        acot x == series acot(coefficients x)$STNC
+
+        asec x == series asec(coefficients x)$STNC
+
+        acsc x == series acsc(coefficients x)$STNC
+
+        sinh x == series sinh(coefficients x)$STNC
+
+        cosh x == series cosh(coefficients x)$STNC
+
+        tanh x == series tanh(coefficients x)$STNC
+
+        coth x == series coth(coefficients x)$STNC
+
+        sech x == series sech(coefficients x)$STNC
+
+        csch x == series csch(coefficients x)$STNC
+
+        asinh x == series asinh(coefficients x)$STNC
+
+        acosh x == series acosh(coefficients x)$STNC
+
+        atanh x == series atanh(coefficients x)$STNC
+
+        acoth x == series acoth(coefficients x)$STNC
+
+        asech x == series asech(coefficients x)$STNC
+
+        acsch x == series acsch(coefficients x)$STNC
+
+@
+<<UTSCAT.dotabb>>=
+"UTSCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UTSCAT"];
+"UTSCAT" -> "UPSCAT"
+
+@
+<<UTSCAT.dotfull>>=
+"UnivariateTaylorSeriesCategory(a:Ring)" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UTSCAT"];
+"UnivariateTaylorSeriesCategory(a:Ring)" ->
+    "UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)"
+
+@
+<<UTSCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"UnivariateTaylorSeriesCategory(a:Ring)" [color=lightblue];
+"UnivariateTaylorSeriesCategory(a:Ring)" ->
+    "UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)"
+
+"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" 
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=UPSCAT"];
+"UnivariatePowerSeriesCategory(a:Ring,NonNegativeInteger)" -> 
+    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
+ [color=lightblue];
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
+ "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+ [color=seagreen];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+ [color=lightblue];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
+    "AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)"
+
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" [color=lightblue];
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> "RING..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "BIMODULE..."
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "IntegralDomain()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CharacteristicNonZero()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "CommutativeRing()"
+"AbelianMonoidRing(a:Ring,b:OrderedAbelianMonoid)" -> 
+    "Algebra(Fraction(Integer))"
+
+"IntegralDomain()" [color=lightblue];
+"IntegralDomain()" -> "CommutativeRing()"
+"IntegralDomain()" -> "Algebra(a:CommutativeRing)"
+"IntegralDomain()" -> "EntireRing()"
+
+"EntireRing()" [color=lightblue];
+"EntireRing()" -> "RING..."
+"EntireRing()" -> "BIMODULE..."
+
+"CharacteristicNonZero()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=CHARNZ"];
+"CharacteristicNonZero()" -> "RING..."
+
+"Algebra(Fraction(Integer))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(Fraction(Integer))" -> "Algebra(a:CommutativeRing)"
+
+"Algebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ALGEBRA"];
+"Algebra(a:CommutativeRing)" -> "RING..."
+"Algebra(a:CommutativeRing)" -> "MODULE..."
+
+"CommutativeRing()" [color=lightblue];
+"CommutativeRing()" -> "RING..."
+"CommutativeRing()" -> "BIMODULE..."
+
+"BIMODULE..." [color=lightblue];
+"RING..." [color=lightblue];
+"MODULE..." [color=lightblue];
+}
+
+@
+\chapter{Category Layer 16}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{AlgebraicallyClosedField}{ACF}
 \pagepic{ps/v102algebraicallyclosedfield.ps}{ACF}{0.75}
@@ -40759,487 +44041,6 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{DirectProductCategory}{DIRPCAT}
-\pagepic{ps/v102directproductcategory.ps}{DIRPCAT}{0.40}
-
-{\bf See:}\\
-\pagefrom{BiModule}{BMODULE}
-\pagefrom{CoercibleTo}{KOERCE}
-\pagefrom{DifferentialExtension}{DIFEXT}
-\pagefrom{IndexedAggregate}{IXAGG}
-\pagefrom{Finite}{FINITE}
-\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
-\pagefrom{FullyRetractableTo}{FRETRCT}
-\pagefrom{OrderedRing}{ORDRING}
-\pagefrom{OrderedAbelianMonoidSup}{OAMONS}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{DIRPCAT}{0} &
-\cross{DIRPCAT}{1} &
-\cross{DIRPCAT}{abs} &
-\cross{DIRPCAT}{any?} &
-\cross{DIRPCAT}{characteristic} \\
-\cross{DIRPCAT}{coerce} &
-\cross{DIRPCAT}{copy} &
-\cross{DIRPCAT}{count} &
-\cross{DIRPCAT}{count} &
-\cross{DIRPCAT}{D} \\
-\cross{DIRPCAT}{differentiate} &
-\cross{DIRPCAT}{dimension} &
-\cross{DIRPCAT}{directProduct} &
-\cross{DIRPCAT}{dot} &
-\cross{DIRPCAT}{elt} \\
-\cross{DIRPCAT}{empty} &
-\cross{DIRPCAT}{empty?} &
-\cross{DIRPCAT}{entry?} &
-\cross{DIRPCAT}{entries} &
-\cross{DIRPCAT}{eq?} \\
-\cross{DIRPCAT}{eval} &
-\cross{DIRPCAT}{every?} &
-\cross{DIRPCAT}{fill!} &
-\cross{DIRPCAT}{first} &
-\cross{DIRPCAT}{hash} \\
-\cross{DIRPCAT}{index} &
-\cross{DIRPCAT}{index?} &
-\cross{DIRPCAT}{indices} &
-\cross{DIRPCAT}{latex} &
-\cross{DIRPCAT}{less?} \\
-\cross{DIRPCAT}{lookup} &
-\cross{DIRPCAT}{map} &
-\cross{DIRPCAT}{map!} &
-\cross{DIRPCAT}{max} &
-\cross{DIRPCAT}{maxIndex} \\
-\cross{DIRPCAT}{member?} &
-\cross{DIRPCAT}{members} &
-\cross{DIRPCAT}{min} &
-\cross{DIRPCAT}{minIndex} &
-\cross{DIRPCAT}{more?} \\
-\cross{DIRPCAT}{negative?} &
-\cross{DIRPCAT}{one?} &
-\cross{DIRPCAT}{parts} &
-\cross{DIRPCAT}{positive?} &
-\cross{DIRPCAT}{qelt} \\
-\cross{DIRPCAT}{qsetelt!} &
-\cross{DIRPCAT}{random} &
-\cross{DIRPCAT}{recip} &
-\cross{DIRPCAT}{reducedSystem} &
-\cross{DIRPCAT}{retract} \\
-\cross{DIRPCAT}{retractIfCan} &
-\cross{DIRPCAT}{sample} &
-\cross{DIRPCAT}{setelt} &
-\cross{DIRPCAT}{sign} &
-\cross{DIRPCAT}{size} \\
-\cross{DIRPCAT}{size?} &
-\cross{DIRPCAT}{subtractIfCan} &
-\cross{DIRPCAT}{sup} &
-\cross{DIRPCAT}{swap!} &
-\cross{DIRPCAT}{unitVector} \\
-\cross{DIRPCAT}{zero?} &
-\cross{DIRPCAT}{?\~{}=?} &
-\cross{DIRPCAT}{-?} &
-\cross{DIRPCAT}{?.?} &
-\cross{DIRPCAT}{\#?} \\
-\cross{DIRPCAT}{?*?} &
-\cross{DIRPCAT}{?**?} &
-\cross{DIRPCAT}{?+?} &
-\cross{DIRPCAT}{?-?} &
-\cross{DIRPCAT}{?/?} \\
-\cross{DIRPCAT}{?$<$?} &
-\cross{DIRPCAT}{?$<=$?} &
-\cross{DIRPCAT}{?=?} &
-\cross{DIRPCAT}{?$>$?} &
-\cross{DIRPCAT}{?$>=$?} \\
-\cross{DIRPCAT}{?\^{}?} &&&&
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{DIRPCAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item if \#2 has commutativeRing then commutative(``*'') where
-{\bf \cross{DIRPCAT}{commutative(``*'')}}
-is true if it has an operation $"*": (D,D) -> D$
-which is commutative.
-\item if \#2 has unitsKnown then unitsKnown where
-{\bf \cross{DIRPCAT}{unitsKnown}}
-is true if a monoid (a multiplicative semigroup with a 1) has 
-unitsKnown means that  the operation {\tt recip} can only return 
-``failed'' if its argument is not a unit.
-\item if \#2 has Ring then rightUnitary where
-{\bf \cross{DIRPCAT}{leftUnitary}}
-is true if $1 * x = x$ for all x.
-\item if \#2 has Ring then rightUnitary where
-{\bf \cross{DIRPCAT}{rightUnitary}}
-is true if $x * 1 = x$ for all x.
-\item {\bf nil}
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- directProduct : Vector R -> %
- dot : (%,%) -> R if R has RING
- unitVector : PositiveInteger -> % if R has RING
- ?*? : (R,%) -> % if R has MONOID
- ?*? : (%,R) -> % if R has MONOID
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- characteristic : () -> NonNegativeInteger if R has RING
- coerce : Integer -> % 
-   if and(has(R,RetractableTo Integer),
-          has(R,SetCategory)) 
-   or R has RING
- differentiate : (%,(R -> R)) -> % if R has RING
- dimension : () -> CardinalNumber if R has FIELD
- reducedSystem : Matrix % -> Matrix R if R has RING
- reducedSystem :
-    (Matrix %,Vector %) ->
-       Record(mat: Matrix R,vec: Vector R) 
-          if R has RING
- size : () -> NonNegativeInteger if R has FINITE
- ?/? : (%,R) -> % if R has FIELD
-\end{verbatim}
-
-These exports come from \refto{IndexedAggregate}(a:SetCategory,R:Type):
-\begin{verbatim}
- any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- coerce : % -> OutputForm if R has SETCAT
- copy : % -> %                        
- count : (R,%) -> NonNegativeInteger 
-   if R has SETCAT 
-   and $ has finiteAggregate
- count : ((R -> Boolean),%) -> NonNegativeInteger 
-   if $ has finiteAggregate
- elt : (%,Integer,R) -> R
- empty : () -> %                      
- empty? : % -> Boolean
- entries : % -> List R                
- entry? : (R,%) -> Boolean 
-   if $ has finiteAggregate 
-   and R has SETCAT
- eq? : (%,%) -> Boolean
- eval : (%,List R,List R) -> % 
-   if R has EVALAB R 
-   and R has SETCAT
- eval : (%,R,R) -> % 
-   if R has EVALAB R 
-   and R has SETCAT
- eval : (%,Equation R) -> % 
-   if R has EVALAB R 
-   and R has SETCAT
- eval : (%,List Equation R) -> % 
-   if R has EVALAB R 
-   and R has SETCAT
- every? : ((R -> Boolean),%) -> Boolean 
-   if $ has finiteAggregate
- fill! : (%,R) -> % if $ has shallowlyMutable
- first : % -> R if Integer has ORDSET
- hash : % -> SingleInteger if R has SETCAT
- index? : (Integer,%) -> Boolean      
- indices : % -> List Integer
- less? : (%,NonNegativeInteger) -> Boolean
- latex : % -> String if R has SETCAT
- map : ((R -> R),%) -> %              
- map! : ((R -> R),%) -> % if $ has shallowlyMutable
- maxIndex : % -> Integer if Integer has ORDSET
- member? : (R,%) -> Boolean 
-   if R has SETCAT 
-   and $ has finiteAggregate
- members : % -> List R if $ has finiteAggregate
- minIndex : % -> Integer if Integer has ORDSET
- more? : (%,NonNegativeInteger) -> Boolean
- parts : % -> List R if $ has finiteAggregate
- qelt : (%,Integer) -> R
- qsetelt! : (%,Integer,R) -> R if $ has shallowlyMutable
- sample : () -> %                     
- setelt : (%,Integer,R) -> R if $ has shallowlyMutable
- size? : (%,NonNegativeInteger) -> Boolean
- swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?.? : (%,Integer) -> R               
- ?=? : (%,%) -> Boolean if R has SETCAT
- ?~=? : (%,%) -> Boolean if R has SETCAT
-\end{verbatim}
-
-These exports come from \refto{CoercibleTo}(Vector(R:Type)):
-\begin{verbatim}
- coerce : % -> Vector R
-\end{verbatim}
-
-These exports come from \refto{FullyRetractableTo}(R:SetCategory):
-\begin{verbatim}
- coerce : R -> % if R has SETCAT
- coerce : Fraction Integer -> % 
-   if and(has(R,RetractableTo Fraction Integer),
-          has(R,SetCategory))
- retract : % -> Integer 
-   if and(has(R,RetractableTo Integer),
-          has(R,SetCategory))
- retract : % -> R if R has SETCAT
- retract : % -> Fraction Integer 
-   if and(has(R,RetractableTo Fraction Integer),
-          has(R,SetCategory))
- retractIfCan : % -> Union(Integer,"failed") 
-   if and(has(R,RetractableTo Integer),
-          has(R,SetCategory))
- retractIfCan : % -> Union(R,"failed") if R has SETCAT
- retractIfCan : % -> Union(Fraction Integer,"failed") 
-   if and(has(R,RetractableTo Fraction Integer),
-          has(R,SetCategory))
-\end{verbatim}
-
-These exports come from \refto{BiModule}(R:Ring,R:Ring):
-\begin{verbatim}
- 0 : () -> % if R has CABMON          
- subtractIfCan : (%,%) -> Union(%,"failed") if R has CABMON
- zero? : % -> Boolean if R has CABMON
- ?+? : (%,%) -> % if R has ABELSG
- ?*? : (PositiveInteger,%) -> % if R has ABELSG
- ?*? : (NonNegativeInteger,%) -> % if R has CABMON
- ?*? : (Integer,%) -> % if R has RING
- ?-? : (%,%) -> % if R has RING
- -? : % -> % if R has RING            
-\end{verbatim}
-
-These exports come from \refto{DifferentialExtension}(R:Ring):
-\begin{verbatim}
- 1 : () -> % if R has RING
- D : (%,(R -> R)) -> % if R has RING
- D : (%,(R -> R),NonNegativeInteger) -> % if R has RING
- D : % -> % if and(has(R,DifferentialRing),has(R,Ring))
- D : (%,NonNegativeInteger) -> % 
-   if and(has(R,DifferentialRing),has(R,Ring))
- differentiate : (%,NonNegativeInteger) -> % 
-   if and(has(R,DifferentialRing),has(R,Ring))
- D : (%,List Symbol,List NonNegativeInteger) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- D : (%,Symbol,NonNegativeInteger) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- D : (%,List Symbol) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- D : (%,Symbol) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- differentiate : (%,Symbol,NonNegativeInteger) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- differentiate : (%,List Symbol) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- differentiate : % -> % 
-   if and(has(R,DifferentialRing),has(R,Ring))
- differentiate : (%,(R -> R),NonNegativeInteger) -> % 
-   if R has RING
- differentiate : (%,Symbol) -> % 
-   if and(has(R,PartialDifferentialRing Symbol),has(R,Ring))
- one? : % -> Boolean if R has RING
- recip : % -> Union(%,"failed") if R has RING
- ?*? : (%,%) -> % if R has RING
- ?**? : (%,PositiveInteger) -> % if R has RING
- ?**? : (%,NonNegativeInteger) -> % if R has RING
- ?^? : (%,PositiveInteger) -> % if R has RING
- ?^? : (%,NonNegativeInteger) -> % if R has RING
-\end{verbatim}
-
-These exports come from \refto{FullyLinearlyExplicitRingOver}(R:Ring):
-\begin{verbatim}
- reducedSystem :
-   (Matrix %,Vector %) -> 
-     Record(mat: Matrix Integer,vec: Vector Integer) 
-       if and(has(R,LinearlyExplicitRingOver Integer),has(R,Ring))
- reducedSystem : Matrix % -> Matrix Integer 
-   if and(has(R,LinearlyExplicitRingOver Integer),has(R,Ring))
-\end{verbatim}
-
-These exports come from \refto{Finite}():
-\begin{verbatim}
- index : PositiveInteger -> % if R has FINITE
- lookup : % -> PositiveInteger if R has FINITE
- random : () -> % if R has FINITE
-\end{verbatim}
-
-These exports come from \refto{OrderedRing}():
-\begin{verbatim}
- abs : % -> % if R has ORDRING
- max : (%,%) -> % if R has ORDRING or R has OAMONS
- min : (%,%) -> % if R has ORDRING or R has OAMONS
- negative? : % -> Boolean if R has ORDRING
- positive? : % -> Boolean if R has ORDRING
- sign : % -> Integer if R has ORDRING
- ?<? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
- ?<=? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
- ?>? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
- ?>=? : (%,%) -> Boolean if R has ORDRING or R has OAMONS
-\end{verbatim}
-
-These exports come from \refto{OrderedAbelianMonoidSup}():
-\begin{verbatim}
- sup : (%,%) -> % if R has OAMONS
-\end{verbatim}
-
-<<category DIRPCAT DirectProductCategory>>=
-)abbrev category DIRPCAT DirectProductCategory
--- all direct product category domains must be compiled
--- without subsumption, set SourceLevelSubset to EQUAL
---)bo $noSubsumption := true
- 
---% DirectProductCategory
- 
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors: DirectProduct
-++ Also See: VectorCategory
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++   This category represents a finite cartesian product of a given type.
-++ Many categorical properties are preserved under this construction.
- 
-DirectProductCategory(dim:NonNegativeInteger, R:Type): Category ==
-  Join(IndexedAggregate(Integer, R), CoercibleTo Vector R) with
-         finiteAggregate
-           ++ attribute to indicate an aggregate of finite size
-         directProduct: Vector R -> %
-           ++ directProduct(v) converts the vector v to become
-           ++ a direct product. Error: if the length of v is
-           ++ different from dim.
-         if R has SetCategory then FullyRetractableTo R
-         if R has Ring then
-           BiModule(R, R)
-           DifferentialExtension R
-           FullyLinearlyExplicitRingOver R
-           unitVector: PositiveInteger -> %
-             ++ unitVector(n) produces a vector with 1 in position n and
-             ++ zero elsewhere.
-           dot: (%, %) -> R
-             ++ dot(x,y) computes the inner product of the vectors x and y.
-         if R has AbelianSemiGroup then AbelianSemiGroup
-         if R has CancellationAbelianMonoid then CancellationAbelianMonoid
-         if R has Monoid then
-            Monoid
-           _* : (R, %) -> %
-             ++ r * y multiplies the element r times each component of the
-             ++ vector y.
-           _* : (%, R) -> %
-             ++ y*r multiplies each component of the vector y by the element r.
-         if R has Finite then Finite
-         if R has CommutativeRing then
-           Algebra R
-           CommutativeRing
-         if R has unitsKnown then unitsKnown
-         if R has OrderedRing then OrderedRing
-         if R has OrderedAbelianMonoidSup then OrderedAbelianMonoidSup
-         if R has Field then VectorSpace R
- add
-      if R has Ring then
-        equation2R: Vector % -> Matrix R
- 
-        coerce(n:Integer):%          == n::R::%
-
-        characteristic()             == characteristic()$R
-
-        differentiate(z:%, d:R -> R) == map(d, z)
- 
-        equation2R v ==
-          ans:Matrix(R) := new(dim, #v, 0)
-          for i in minRowIndex ans .. maxRowIndex ans repeat
-            for j in minColIndex ans .. maxColIndex ans repeat
-              qsetelt_!(ans, i, j, qelt(qelt(v, j), i))
-          ans
- 
-        reducedSystem(m:Matrix %):Matrix(R) ==
-          empty? m => new(0, 0, 0)
-          reduce(vertConcat, [equation2R row(m, i)
-                 for i in minRowIndex m .. maxRowIndex m])$List(Matrix R)
- 
-        reducedSystem(m:Matrix %, v:Vector %):
-          Record(mat:Matrix R, vec:Vector R) ==
-            vh:Vector(R) :=
-              empty? v => empty()
-              rh := reducedSystem(v::Matrix %)@Matrix(R)
-              column(rh, minColIndex rh)
-            [reducedSystem(m)@Matrix(R), vh]
- 
-      if R has Finite then size == size$R ** dim
- 
-      if R has Field then
-        x / b       == x * inv b
-
-        dimension() == dim::CardinalNumber
- 
-@
-<<DIRPCAT.dotabb>>=
-"DIRPCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=DIRPCAT"];
-"DIRPCAT" -> "IXAGG"
-"DIRPCAT" -> "KOERCE"
-"DIRPCAT" -> "FRETRCT"
-"DIRPCAT" -> "BMODULE"
-"DIRPCAT" -> "DIFEXT"
-"DIRPCAT" -> "FLINEXP"
-"DIRPCAT" -> "FINITE"
-"DIRPCAT" -> "ORDRING"
-"DIRPCAT" -> "OAMONS"
-
-@
-<<DIRPCAT.dotfull>>=
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=DIRPCAT"];
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "IndexedAggregate(a:SetCategory,b:Type)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "CoercibleTo(a:Type)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "FullyRetractableTo(a:Type)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "BiModule(a:Ring,b:Ring)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "DifferentialExtension(a:Ring)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "FullyLinearlyExplicitRingOver(a:Ring)"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "Finite()"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "OrderedRing()"
-"DirectProductCategory(a:NonNegativeInteger,b:Type)"
-  -> "OrderedAbelianMonoidSup()"
-
-@
-<<DIRPCAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" [color=lightblue];
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "BMODULE..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "KOERCE..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "DIFEXT..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FINITE..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FLINEXP..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "FRETRCT..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "IXAGG..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "OAMONS..."
-"DirectProductCategory(a:NonNegativeInteger,b:Type)" -> "ORDRING..."
-
-"BMODULE..." [color=lightblue];
-"KOERCE..." [color=lightblue];
-"DIFEXT..." [color=lightblue];
-"FINITE..." [color=lightblue];
-"FLINEXP..." [color=lightblue];
-"FRETRCT..." [color=lightblue];
-"IXAGG..." [color=lightblue];
-"OAMONS..." [color=lightblue];
-"ORDRING..." [color=lightblue];
-
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FieldOfPrimeCharacteristic}{FPC}
 \pagepic{ps/v102fieldofprimecharacteristic.ps}{FPC}{1.00}
 
@@ -42918,6 +45719,16 @@ FunctionSpace(R:OrderedSet): Category == Definition where
 "FS" -> "FRETRCT"
 "FS" -> "PATAB"
 "FS" -> "RETRACT"
+"FS" -> "KONVERT"
+"FS" -> "MONOID"
+"FS" -> "GROUP"
+"FS" -> "ABELMON"
+"FS" -> "ABELGRP"
+"FS" -> "PDRING"
+"FS" -> "FLINEXP"
+"FS" -> "CHARNZ"
+"FS" -> "INTDOM"
+"FS" -> "FIELD"
 
 @
 <<FS.dotfull>>=
@@ -42928,6 +45739,18 @@ FunctionSpace(R:OrderedSet): Category == Definition where
 "FunctionSpace(a:OrderedSet)" -> "Patternable(OrderedSet)"
 "FunctionSpace(a:OrderedSet)" -> "FullyPatternMatchable(OrderedSet)"
 "FunctionSpace(a:OrderedSet)" -> "FullyRetractableTo(OrderedSet)"
+"FunctionSpace(a:OrderedSet)" -> "ConvertibleTo(InputForm)"
+"FunctionSpace(a:OrderedSet)" -> "Monoid()"
+"FunctionSpace(a:OrderedSet)" -> "Group()"
+"FunctionSpace(a:OrderedSet)" -> "AbelianMonoid()"
+"FunctionSpace(a:OrderedSet)" -> "AbelianGroup()"
+"FunctionSpace(a:OrderedSet)" -> "PartialDifferentialRing(Symbol)"
+"FunctionSpace(a:OrderedSet)" -> "FullyLinearlyExplicitRingOver(OrderedSet)"
+"FunctionSpace(a:OrderedSet)" -> "CharacteristicNonZero()"
+"FunctionSpace(a:OrderedSet)" -> "IntegralDomain()"
+"FunctionSpace(a:OrderedSet)" -> "Field()"
+"FunctionSpace(a:OrderedSet)" -> "RetractableTo(Integer)"
+"FunctionSpace(a:OrderedSet)" -> "RetractableTo(Fraction(Integer))"
 
 @
 <<FS.dotpic>>=
@@ -42937,18 +45760,24 @@ digraph pic {
  node [shape=box, color=white, style=filled];
 
 "FunctionSpace(a:OrderedSet)" [color=lightblue];
-"FunctionSpace(a:OrderedSet)" -> "ExpressionSpace()"
+"FunctionSpace(a:OrderedSet)" -> "ES..."
 "FunctionSpace(a:OrderedSet)" -> "RETRACT..."
 "FunctionSpace(a:OrderedSet)" -> "PATAB..."
 "FunctionSpace(a:OrderedSet)" -> "FPATMAB..."
 "FunctionSpace(a:OrderedSet)" -> "FRETRCT..."
+"FunctionSpace(a:OrderedSet)" -> "KONVERT..."
+"FunctionSpace(a:OrderedSet)" -> "MONOID..."
+"FunctionSpace(a:OrderedSet)" -> "GROUP..."
+"FunctionSpace(a:OrderedSet)" -> "ABELMON..."
+"FunctionSpace(a:OrderedSet)" -> "ABELGRP..."
+"FunctionSpace(a:OrderedSet)" -> "PDRING..."
+"FunctionSpace(a:OrderedSet)" -> "FLINEXP..."
+"FunctionSpace(a:OrderedSet)" -> "CHARNZ..."
+"FunctionSpace(a:OrderedSet)" -> "INTDOM..."
+"FunctionSpace(a:OrderedSet)" -> "FIELD..."
+"FunctionSpace(a:OrderedSet)" -> "RETRACT..."
 
-"ExpressionSpace()" [color=lightblue];
-"ExpressionSpace()" -> "ORDSET..."
-"ExpressionSpace()" -> "RETRACT..."
-"ExpressionSpace()" -> "IEVALAB..."
-"ExpressionSpace()" -> "EVALABLE..."
-
+"ES..." [color=lightblue];
 "EVALABLE..." [color=lightblue];
 "FRETRCT..." [color=lightblue];
 "FPATMAB..." [color=lightblue];
@@ -42956,797 +45785,17 @@ digraph pic {
 "ORDSET..." [color=lightblue];
 "PATAB..." [color=lightblue];
 "RETRACT..." [color=lightblue];
-}
-
-@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{MatrixCategory}{MATCAT}
-\pagepic{ps/v102matrixcategory.ps}{MATCAT}{0.60}
-
-{\bf See:}\\
-\pagefrom{TwoDimensionalArrayCategory}{ARR2CAT}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{MATCAT}{antisymmetric?} &
-\cross{MATCAT}{any?} &
-\cross{MATCAT}{coerce} &
-\cross{MATCAT}{column} &
-\cross{MATCAT}{copy} \\
-\cross{MATCAT}{count} &
-\cross{MATCAT}{determinant} &
-\cross{MATCAT}{diagonal?} &
-\cross{MATCAT}{diagonalMatrix} &
-\cross{MATCAT}{elt} \\
-\cross{MATCAT}{empty} &
-\cross{MATCAT}{empty?} &
-\cross{MATCAT}{eq?} &
-\cross{MATCAT}{eval} &
-\cross{MATCAT}{every?} \\
-\cross{MATCAT}{exquo} &
-\cross{MATCAT}{fill!} &
-\cross{MATCAT}{hash} &
-\cross{MATCAT}{horizConcat} &
-\cross{MATCAT}{inverse} \\
-\cross{MATCAT}{latex} &
-\cross{MATCAT}{less?} &
-\cross{MATCAT}{listOfLists} &
-\cross{MATCAT}{map} &
-\cross{MATCAT}{map!} \\
-\cross{MATCAT}{matrix} &
-\cross{MATCAT}{maxColIndex} &
-\cross{MATCAT}{maxRowIndex} &
-\cross{MATCAT}{member?} &
-\cross{MATCAT}{members} \\
-\cross{MATCAT}{minColIndex} &
-\cross{MATCAT}{minordet} &
-\cross{MATCAT}{minRowIndex} &
-\cross{MATCAT}{more?} &
-\cross{MATCAT}{ncols} \\
-\cross{MATCAT}{new} &
-\cross{MATCAT}{nrows} &
-\cross{MATCAT}{nullSpace} &
-\cross{MATCAT}{nullity} &
-\cross{MATCAT}{parts} \\
-\cross{MATCAT}{qelt} &
-\cross{MATCAT}{qsetelt!} &
-\cross{MATCAT}{rank} &
-\cross{MATCAT}{row} &
-\cross{MATCAT}{rowEchelon} \\
-\cross{MATCAT}{sample} &
-\cross{MATCAT}{scalarMatrix} &
-\cross{MATCAT}{setColumn!} &
-\cross{MATCAT}{setelt} &
-\cross{MATCAT}{setRow!} \\
-\cross{MATCAT}{setsubMatrix!} &
-\cross{MATCAT}{size?} &
-\cross{MATCAT}{square?} &
-\cross{MATCAT}{squareTop} &
-\cross{MATCAT}{subMatrix} \\
-\cross{MATCAT}{swapColumns!} &
-\cross{MATCAT}{swapRows!} &
-\cross{MATCAT}{symmetric?} &
-\cross{MATCAT}{transpose} &
-\cross{MATCAT}{vertConcat} \\
-\cross{MATCAT}{zero} &
-\cross{MATCAT}{\#?} &
-\cross{MATCAT}{?**?} &
-\cross{MATCAT}{?/?} &
-\cross{MATCAT}{?=?} \\
-\cross{MATCAT}{?\~{}=?} &
-\cross{MATCAT}{?*?} &
-\cross{MATCAT}{?+?} &
-\cross{MATCAT}{-?} &
-\cross{MATCAT}{?-?} \\
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{MATCAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf \cross{MATCAT}{shallowlyMutable}}
-is true if its values have immediate components that are 
-updateable (mutable). Note: the properties of any component 
-domain are irrevelant to the shallowlyMutable proper.
-\item {\bf nil}
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- determinant : % -> R if R has commutative *
- inverse : % -> Union(%,"failed") if R has FIELD
- minordet : % -> R if R has commutative *
- nullity : % -> NonNegativeInteger if R has INTDOM
- nullSpace : % -> List Col if R has INTDOM
- rowEchelon : % -> % if R has EUCDOM
- rank : % -> NonNegativeInteger if R has INTDOM
-\end{verbatim}
-
-These are implemented by this category:
-\begin{verbatim}
- antisymmetric? : % -> Boolean
- coerce : Col -> %                    
- diagonal? : % -> Boolean
- diagonalMatrix : List % -> %         
- diagonalMatrix : List R -> %
- elt : (%,List Integer,List Integer) -> %
- exquo : (%,R) -> Union(%,"failed") if R has INTDOM
- horizConcat : (%,%) -> %             
- listOfLists : % -> List List R
- matrix : List List R -> %            
- scalarMatrix : (NonNegativeInteger,R) -> %
- setelt : (%,List Integer,List Integer,%) -> %
- setsubMatrix! : (%,Integer,Integer,%) -> %
- square? : % -> Boolean               
- squareTop : % -> %
- subMatrix : (%,Integer,Integer,Integer,Integer) -> %
- swapColumns! : (%,Integer,Integer) -> %
- swapRows! : (%,Integer,Integer) -> %
- symmetric? : % -> Boolean            
- transpose : Row -> %                 
- transpose : % -> %
- vertConcat : (%,%) -> %
- zero : (NonNegativeInteger,NonNegativeInteger) -> %
- ?/? : (%,R) -> % if R has FIELD
- ?+? : (%,%) -> %                     
- ?-? : (%,%) -> %                     
- -? : % -> %
- ?*? : (%,R) -> %
- ?*? : (R,%) -> %                     
- ?*? : (Integer,%) -> %               
- ?**? : (%,NonNegativeInteger) -> %
- ?**? : (%,Integer) -> % if R has FIELD
- ?*? : (%,Col) -> Col
- ?*? : (Row,%) -> Row                 
- ?*? : (%,%) -> %
-\end{verbatim}
-
-These exports come from \refto{TwoDimensionalArrayCategory}(R,Row,Col)\\
-where R:Ring, Row:FiniteLinearAggregate(R),\\
-Col:FiniteLinearAggregate(R):
-\begin{verbatim}
- any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- coerce : % -> OutputForm if R has SETCAT
- column : (%,Integer) -> Col
- copy : % -> %                        
- count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
- count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- elt : (%,Integer,Integer,R) -> R     
- elt : (%,Integer,Integer) -> R
- empty : () -> %                      
- empty? : % -> Boolean
- eq? : (%,%) -> Boolean               
- eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
- eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
- every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- fill! : (%,R) -> %
- hash : % -> SingleInteger if R has SETCAT
- latex : % -> String if R has SETCAT
- less? : (%,NonNegativeInteger) -> Boolean
- map : (((R,R) -> R),%,%,R) -> %      
- map : (((R,R) -> R),%,%) -> %
- map : ((R -> R),%) -> %              
- map! : ((R -> R),%) -> %
- maxColIndex : % -> Integer
- maxRowIndex : % -> Integer           
- member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
- members : % -> List R if $ has finiteAggregate
- minColIndex : % -> Integer
- minRowIndex : % -> Integer           
- more? : (%,NonNegativeInteger) -> Boolean
- new : (NonNegativeInteger,NonNegativeInteger,R) -> %
- ncols : % -> NonNegativeInteger
- nrows : % -> NonNegativeInteger      
- parts : % -> List R
- qelt : (%,Integer,Integer) -> R      
- qsetelt! : (%,Integer,Integer,R) -> R
- row : (%,Integer) -> Row
- sample : () -> %                     
- setColumn! : (%,Integer,Col) -> %
- setelt : (%,Integer,Integer,R) -> R
- setRow! : (%,Integer,Row) -> %
- size? : (%,NonNegativeInteger) -> Boolean
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?~=? : (%,%) -> Boolean if R has SETCAT
- ?=? : (%,%) -> Boolean if R has SETCAT
-\end{verbatim}
-
-<<category MATCAT MatrixCategory>>=
-)abbrev category MATCAT MatrixCategory
-++ Authors: Grabmeier, Gschnitzer, Williamson
-++ Date Created: 1987
-++ Date Last Updated: July 1990
-++ Basic Operations:
-++ Related Domains: Matrix(R)
-++ Also See:
-++ AMS Classifications:
-++ Keywords: matrix, linear algebra
-++ Examples:
-++ References:
-++ Description:
-++   \spadtype{MatrixCategory} is a general matrix category which allows
-++   different representations and indexing schemes.  Rows and
-++   columns may be extracted with rows returned as objects of
-++   type Row and colums returned as objects of type Col.
-++   A domain belonging to this category will be shallowly mutable.
-++   The index of the 'first' row may be obtained by calling the
-++   function \spadfun{minRowIndex}.  The index of the 'first' column may
-++   be obtained by calling the function \spadfun{minColIndex}.  The index of
-++   the first element of a Row is the same as the index of the
-++   first column in a matrix and vice versa.
-MatrixCategory(R,Row,Col): Category == Definition where
-  R   : Ring
-  Row : FiniteLinearAggregate R
-  Col : FiniteLinearAggregate R
-
-  Definition ==> TwoDimensionalArrayCategory(R,Row,Col) with
-     shallowlyMutable
-       ++ One may destructively alter matrices
-
-     finiteAggregate
-       ++ matrices are finite
-
---% Predicates
-
-     square?  : % -> Boolean
-       ++ \spad{square?(m)} returns true if m is a square matrix
-       ++ (if m has the same number of rows as columns) and false otherwise.
-     diagonal?: % -> Boolean
-       ++ \spad{diagonal?(m)} returns true if the matrix m is square and
-       ++ diagonal (i.e. all entries of m not on the diagonal are zero) and
-       ++ false otherwise.
-     symmetric?: % -> Boolean
-       ++ \spad{symmetric?(m)} returns true if the matrix m is square and
-       ++ symmetric (i.e. \spad{m[i,j] = m[j,i]} for all i and j) and false
-       ++ otherwise.
-     antisymmetric?: % -> Boolean
-       ++ \spad{antisymmetric?(m)} returns true if the matrix m is square and
-       ++ antisymmetric (i.e. \spad{m[i,j] = -m[j,i]} for all i and j) 
-       ++ and false otherwise.
-
---% Creation
-
-     zero: (NonNegativeInteger,NonNegativeInteger) -> %
-       ++ \spad{zero(m,n)} returns an m-by-n zero matrix.
-     matrix: List List R -> %
-       ++ \spad{matrix(l)} converts the list of lists l to a matrix, where the
-       ++ list of lists is viewed as a list of the rows of the matrix.
-     scalarMatrix: (NonNegativeInteger,R) -> %
-       ++ \spad{scalarMatrix(n,r)} returns an n-by-n matrix with r's on the
-       ++ diagonal and zeroes elsewhere.
-     diagonalMatrix: List R -> %
-       ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
-       ++ of l on the diagonal.
-     diagonalMatrix: List % -> %
-       ++ \spad{diagonalMatrix([m1,...,mk])} creates a block diagonal matrix
-       ++ M with block matrices {\em m1},...,{\em mk} down the diagonal,
-       ++ with 0 block matrices elsewhere.
-       ++ More precisly: if \spad{ri := nrows mi}, \spad{ci := ncols mi},
-       ++ then m is an (r1+..+rk) by (c1+..+ck) - matrix  with entries
-       ++ \spad{m.i.j = ml.(i-r1-..-r(l-1)).(j-n1-..-n(l-1))}, if
-       ++ \spad{(r1+..+r(l-1)) < i <= r1+..+rl} and
-       ++ \spad{(c1+..+c(l-1)) < i <= c1+..+cl},
-       ++ \spad{m.i.j} = 0  otherwise.
-     coerce: Col -> %
-       ++ \spad{coerce(col)} converts the column col to a column matrix.
-     transpose: Row -> %
-       ++ \spad{transpose(r)} converts the row r to a row matrix.
-
---% Creation of new matrices from old
-
-     transpose: % -> %
-       ++ \spad{transpose(m)} returns the transpose of the matrix m.
-     squareTop: % -> %
-       ++ \spad{squareTop(m)} returns an n-by-n matrix consisting of the first
-       ++ n rows of the m-by-n matrix m. Error: if
-       ++ \spad{m < n}.
-     horizConcat: (%,%) -> %
-       ++ \spad{horizConcat(x,y)} horizontally concatenates two matrices with
-       ++ an equal number of rows. The entries of y appear to the right
-       ++ of the entries of x.  Error: if the matrices
-       ++ do not have the same number of rows.
-     vertConcat: (%,%) -> %
-       ++ \spad{vertConcat(x,y)} vertically concatenates two matrices with an
-       ++ equal number of columns. The entries of y appear below
-       ++ of the entries of x.  Error: if the matrices
-       ++ do not have the same number of columns.
-
---% Part extractions/assignments
-
-     listOfLists: % -> List List R
-       ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
-       ++ of lists.
-     elt: (%,List Integer,List Integer) -> %
-       ++ \spad{elt(x,rowList,colList)} returns an m-by-n matrix consisting
-       ++ of elements of x, where \spad{m = # rowList} and \spad{n = # colList}
-       ++ If \spad{rowList = [i<1>,i<2>,...,i<m>]} and \spad{colList =
-       ++ [j<1>,j<2>,...,j<n>]}, then the \spad{(k,l)}th entry of
-       ++ \spad{elt(x,rowList,colList)} is \spad{x(i<k>,j<l>)}.
-     setelt: (%,List Integer,List Integer, %) -> %
-       ++ \spad{setelt(x,rowList,colList,y)} destructively alters the matrix x.
-       ++ If y is \spad{m}-by-\spad{n}, \spad{rowList = [i<1>,i<2>,...,i<m>]}
-       ++ and \spad{colList = [j<1>,j<2>,...,j<n>]}, then \spad{x(i<k>,j<l>)}
-       ++ is set to \spad{y(k,l)} for \spad{k = 1,...,m} and \spad{l = 1,...,n}
-     swapRows_!: (%,Integer,Integer) -> %
-       ++ \spad{swapRows!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
-       ++ rows of m. This destructively alters the matrix.
-     swapColumns_!: (%,Integer,Integer) -> %
-       ++ \spad{swapColumns!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
-       ++ columns of m. This destructively alters the matrix.
-     subMatrix: (%,Integer,Integer,Integer,Integer) -> %
-       ++ \spad{subMatrix(x,i1,i2,j1,j2)} extracts the submatrix
-       ++ \spad{[x(i,j)]} where the index i ranges from \spad{i1} to \spad{i2}
-       ++ and the index j ranges from \spad{j1} to \spad{j2}.
-     setsubMatrix_!: (%,Integer,Integer,%) -> %
-       ++ \spad{setsubMatrix(x,i1,j1,y)} destructively alters the
-       ++ matrix x. Here \spad{x(i,j)} is set to \spad{y(i-i1+1,j-j1+1)} for
-       ++ \spad{i = i1,...,i1-1+nrows y} and \spad{j = j1,...,j1-1+ncols y}.
-
---% Arithmetic
-
-     "+": (%,%) -> %
-       ++ \spad{x + y} is the sum of the matrices x and y.
-       ++ Error: if the dimensions are incompatible.
-     "-": (%,%) -> %
-       ++ \spad{x - y} is the difference of the matrices x and y.
-       ++ Error: if the dimensions are incompatible.
-     "-":  %    -> %
-       ++ \spad{-x} returns the negative of the matrix x.
-     "*": (%,%) -> %
-       ++ \spad{x * y} is the product of the matrices x and y.
-       ++ Error: if the dimensions are incompatible.
-     "*": (R,%) -> %
-       ++ \spad{r*x} is the left scalar multiple of the scalar r and the
-       ++ matrix x.
-     "*": (%,R) -> %
-       ++ \spad{x * r} is the right scalar multiple of the scalar r and the
-       ++ matrix x.
-     "*": (Integer,%) -> %
-       ++ \spad{n * x} is an integer multiple.
-     "*": (%,Col) -> Col
-       ++ \spad{x * c} is the product of the matrix x and the column vector c.
-       ++ Error: if the dimensions are incompatible.
-     "*": (Row,%) -> Row
-       ++ \spad{r * x} is the product of the row vector r and the matrix x.
-       ++ Error: if the dimensions are incompatible.
-     "**": (%,NonNegativeInteger) -> %
-       ++ \spad{x ** n} computes a non-negative integral power of the matrix x.
-       ++ Error: if the matrix is not square.
-     if R has IntegralDomain then
-       "exquo": (%,R) -> Union(%,"failed")
-         ++ \spad{exquo(m,r)} computes the exact quotient of the elements
-         ++ of m by r, returning \axiom{"failed"} if this is not possible.
-     if R has Field then
-       "/": (%,R) -> %
-         ++ \spad{m/r} divides the elements of m by r. Error: if \spad{r = 0}.
-
---% Linear algebra
-
-     if R has EuclideanDomain then
-       rowEchelon: % -> %
-         ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
-     if R has IntegralDomain then
-       rank: % -> NonNegativeInteger
-         ++ \spad{rank(m)} returns the rank of the matrix m.
-       nullity: % -> NonNegativeInteger
-         ++ \spad{nullity(m)} returns the nullity of the matrix m. This is
-         ++ the dimension of the null space of the matrix m.
-       nullSpace: % -> List Col
-         ++ \spad{nullSpace(m)} returns a basis for the null space of
-         ++ the matrix m.
-     if R has commutative("*") then
-       determinant: % -> R
-         ++ \spad{determinant(m)} returns the determinant of the matrix m.
-         ++ Error: if the matrix is not square.
-       minordet: % -> R
-         ++ \spad{minordet(m)} computes the determinant of the matrix m using
-         ++ minors. Error: if the matrix is not square.
-     if R has Field then
-       inverse: % -> Union(%,"failed")
-         ++ \spad{inverse(m)} returns the inverse of the matrix m.
-         ++ If the matrix is not invertible, "failed" is returned.
-         ++ Error: if the matrix is not square.
-       "**": (%,Integer) -> %
-         ++ \spad{m**n} computes an integral power of the matrix m.
-         ++ Error: if matrix is not square or if the matrix
-         ++ is square but not invertible.
-
-   add
-     minr ==> minRowIndex
-     maxr ==> maxRowIndex
-     minc ==> minColIndex
-     maxc ==> maxColIndex
-     mini ==> minIndex
-     maxi ==> maxIndex
-
---% Predicates
-
-     square? x == nrows x = ncols x
-
-     diagonal? x ==
-       not square? x => false
-       for i in minr x .. maxr x repeat
-         for j in minc x .. maxc x | (j - minc x) ^= (i - minr x) repeat
-           not zero? qelt(x, i, j) => return false
-       true
-
-     symmetric? x ==
-       (nRows := nrows x) ^= ncols x => false
-       mr := minRowIndex x; mc := minColIndex x
-       for i in 0..(nRows - 1) repeat
-         for j in (i + 1)..(nRows - 1) repeat
-           qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
-       true
-
-     antisymmetric? x ==
-       (nRows := nrows x) ^= ncols x => false
-       mr := minRowIndex x; mc := minColIndex x
-       for i in 0..(nRows - 1) repeat
-         for j in i..(nRows - 1) repeat
-           qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
-             return false
-       true
-
---% Creation of matrices
-
-     zero(rows,cols) == new(rows,cols,0)
-
-     matrix(l: List List R) ==
-       null l => new(0,0,0)
-       -- error check: this is a top level function
-       rows : NonNegativeInteger := 1; cols := # first l
-       cols = 0 => error "matrices with zero columns are not supported"
-       for ll in rest l repeat
-         cols ^= # ll => error "matrix: rows of different lengths"
-         rows := rows + 1
-       ans := new(rows,cols,0)
-       for i in minr(ans)..maxr(ans) for ll in l repeat
-         for j in minc(ans)..maxc(ans) for r in ll repeat
-           qsetelt_!(ans,i,j,r)
-       ans
-
-     scalarMatrix(n,r) ==
-       ans := zero(n,n)
-       for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) repeat
-         qsetelt_!(ans,i,j,r)
-       ans
-
-     diagonalMatrix(l: List R) ==
-       n := #l; ans := zero(n,n)
-       for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) _
-           for r in l repeat qsetelt_!(ans,i,j,r)
-       ans
-
-     diagonalMatrix(list: List %) ==
-       rows : NonNegativeInteger := 0
-       cols : NonNegativeInteger := 0
-       for mat in list repeat
-         rows := rows + nrows mat
-         cols := cols + ncols mat
-       ans := zero(rows,cols)
-       loR := minr ans; loC := minc ans
-       for mat in list repeat
-         hiR := loR + nrows(mat) - 1; hiC := loC + nrows(mat) - 1
-         for i in loR..hiR for k in minr(mat)..maxr(mat) repeat
-           for j in loC..hiC for l in minc(mat)..maxc(mat) repeat
-             qsetelt_!(ans,i,j,qelt(mat,k,l))
-         loR := hiR + 1; loC := hiC + 1
-       ans
-
-     coerce(v:Col) ==
-       x := new(#v,1,0)
-       one := minc(x)
-       for i in minr(x)..maxr(x) for k in mini(v)..maxi(v) repeat
-         qsetelt_!(x,i,one,qelt(v,k))
-       x
-
-     transpose(v:Row) ==
-       x := new(1,#v,0)
-       one := minr(x)
-       for j in minc(x)..maxc(x) for k in mini(v)..maxi(v) repeat
-         qsetelt_!(x,one,j,qelt(v,k))
-       x
-
-     transpose(x:%) ==
-       ans := new(ncols x,nrows x,0)
-       for i in minr(ans)..maxr(ans) repeat
-         for j in minc(ans)..maxc(ans) repeat
-           qsetelt_!(ans,i,j,qelt(x,j,i))
-       ans
-
-     squareTop x ==
-       nrows x < (cols := ncols x) =>
-         error "squareTop: number of columns exceeds number of rows"
-       ans := new(cols,cols,0)
-       for i in minr(x)..(minr(x) + cols - 1) repeat
-         for j in minc(x)..maxc(x) repeat
-           qsetelt_!(ans,i,j,qelt(x,i,j))
-       ans
-
-     horizConcat(x,y) ==
-       (rows := nrows x) ^= nrows y =>
-         error "HConcat: matrices must have same number of rows"
-       ans := new(rows,(cols := ncols x) + ncols y,0)
-       for i in minr(x)..maxr(x) repeat
-         for j in minc(x)..maxc(x) repeat
-           qsetelt_!(ans,i,j,qelt(x,i,j))
-       for i in minr(y)..maxr(y) repeat
-         for j in minc(y)..maxc(y) repeat
-           qsetelt_!(ans,i,j + cols,qelt(y,i,j))
-       ans
-
-     vertConcat(x,y) ==
-       (cols := ncols x) ^= ncols y =>
-         error "HConcat: matrices must have same number of columns"
-       ans := new((rows := nrows x) + nrows y,cols,0)
-       for i in minr(x)..maxr(x) repeat
-         for j in minc(x)..maxc(x) repeat
-           qsetelt_!(ans,i,j,qelt(x,i,j))
-       for i in minr(y)..maxr(y) repeat
-         for j in minc(y)..maxc(y) repeat
-           qsetelt_!(ans,i + rows,j,qelt(y,i,j))
-       ans
-
---% Part extraction/assignment
-
-     listOfLists x ==
-       ll : List List R := nil()
-       for i in maxr(x)..minr(x) by -1 repeat
-         l : List R := nil()
-         for j in maxc(x)..minc(x) by -1 repeat
-           l := cons(qelt(x,i,j),l)
-         ll := cons(l,ll)
-       ll
-
-     swapRows_!(x,i1,i2) ==
-       (i1 < minr(x)) or (i1 > maxr(x)) or (i2 < minr(x)) or _
-           (i2 > maxr(x)) => error "swapRows!: index out of range"
-       i1 = i2 => x
-       for j in minc(x)..maxc(x) repeat
-         r := qelt(x,i1,j)
-         qsetelt_!(x,i1,j,qelt(x,i2,j))
-         qsetelt_!(x,i2,j,r)
-       x
-
-     swapColumns_!(x,j1,j2) ==
-       (j1 < minc(x)) or (j1 > maxc(x)) or (j2 < minc(x)) or _
-           (j2 > maxc(x)) => error "swapColumns!: index out of range"
-       j1 = j2 => x
-       for i in minr(x)..maxr(x) repeat
-         r := qelt(x,i,j1)
-         qsetelt_!(x,i,j1,qelt(x,i,j2))
-         qsetelt_!(x,i,j2,r)
-       x
-
-     elt(x:%,rowList:List Integer,colList:List Integer) ==
-       for ei in rowList repeat
-         (ei < minr(x)) or (ei > maxr(x)) =>
-           error "elt: index out of range"
-       for ej in colList repeat
-         (ej < minc(x)) or (ej > maxc(x)) =>
-           error "elt: index out of range"
-       y := new(# rowList,# colList,0)
-       for ei in rowList for i in minr(y)..maxr(y) repeat
-         for ej in colList for j in minc(y)..maxc(y) repeat
-           qsetelt_!(y,i,j,qelt(x,ei,ej))
-       y
-
-     setelt(x:%,rowList:List Integer,colList:List Integer,y:%) ==
-       for ei in rowList repeat
-         (ei < minr(x)) or (ei > maxr(x)) =>
-           error "setelt: index out of range"
-       for ej in colList repeat
-         (ej < minc(x)) or (ej > maxc(x)) =>
-           error "setelt: index out of range"
-       ((# rowList) ^= (nrows y)) or ((# colList) ^= (ncols y)) =>
-         error "setelt: matrix has bad dimensions"
-       for ei in rowList for i in minr(y)..maxr(y) repeat
-         for ej in colList for j in minc(y)..maxc(y) repeat
-           qsetelt_!(x,ei,ej,qelt(y,i,j))
-       y
-
-     subMatrix(x,i1,i2,j1,j2) ==
-       (i2 < i1) => error "subMatrix: bad row indices"
-       (j2 < j1) => error "subMatrix: bad column indices"
-       (i1 < minr(x)) or (i2 > maxr(x)) =>
-         error "subMatrix: index out of range"
-       (j1 < minc(x)) or (j2 > maxc(x)) =>
-         error "subMatrix: index out of range"
-       rows := (i2 - i1 + 1) pretend NonNegativeInteger
-       cols := (j2 - j1 + 1) pretend NonNegativeInteger
-       y := new(rows,cols,0)
-       for i in minr(y)..maxr(y) for k in i1..i2 repeat
-         for j in minc(y)..maxc(y) for l in j1..j2 repeat
-           qsetelt_!(y,i,j,qelt(x,k,l))
-       y
-
-     setsubMatrix_!(x,i1,j1,y) ==
-       i2 := i1 + nrows(y) -1
-       j2 := j1 + ncols(y) -1
-       (i1 < minr(x)) or (i2 > maxr(x)) =>
-        error _
-         "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
-       (j1 < minc(x)) or (j2 > maxc(x)) =>
-        error _
-         "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
-       for i in minr(y)..maxr(y) for k in i1..i2 repeat
-         for j in minc(y)..maxc(y) for l in j1..j2 repeat
-           qsetelt_!(x,k,l,qelt(y,i,j))
-       x
-
---% Arithmetic
-
-     x + y ==
-       ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
-         error "can't add matrices of different dimensions"
-       ans := new(r,c,0)
-       for i in minr(x)..maxr(x) repeat
-         for j in minc(x)..maxc(x) repeat
-           qsetelt_!(ans,i,j,qelt(x,i,j) + qelt(y,i,j))
-       ans
-
-     x - y ==
-       ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
-         error "can't subtract matrices of different dimensions"
-       ans := new(r,c,0)
-       for i in minr(x)..maxr(x) repeat
-         for j in minc(x)..maxc(x) repeat
-           qsetelt_!(ans,i,j,qelt(x,i,j) - qelt(y,i,j))
-       ans
-
-     - x == map(- #1,x)
-
-     a:R * x:% == map(a * #1,x)
-
-     x:% * a:R == map(#1 * a,x)
-
-     m:Integer * x:% == map(m * #1,x)
-
-     x:% * y:% ==
-       (ncols x ^= nrows y) =>
-         error "can't multiply matrices of incompatible dimensions"
-       ans := new(nrows x,ncols y,0)
-       for i in minr(x)..maxr(x) repeat
-         for j in minc(y)..maxc(y) repeat
-           entry :=
-             sum : R := 0
-             for k in minr(y)..maxr(y) for l in minc(x)..maxc(x) repeat
-               sum := sum + qelt(x,i,l) * qelt(y,k,j)
-             sum
-           qsetelt_!(ans,i,j,entry)
-       ans
-
-     positivePower:(%,Integer) -> %
-     positivePower(x,n) ==
---       one? n => x
-       (n = 1) => x
-       odd? n => x * positivePower(x,n - 1)
-       y := positivePower(x,n quo 2)
-       y * y
-
-     x:% ** n:NonNegativeInteger ==
-       not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
-       zero? n => scalarMatrix(nn,1)
-       positivePower(x,n)
-
-     --if R has ConvertibleTo InputForm then
-       --convert(x:%):InputForm ==
-         --convert [convert("matrix"::Symbol)@InputForm,
-                  --convert listOfLists x]$List(InputForm)
-
-     if Col has shallowlyMutable then
-
-       x:% * v:Col ==
-         ncols(x) ^= #v =>
-           error "can't multiply matrix A and vector v if #cols A ^= #v"
-         w : Col := new(nrows x,0)
-         for i in minr(x)..maxr(x) for k in mini(w)..maxi(w) repeat
-           w.k :=
-             sum : R := 0
-             for j in minc(x)..maxc(x) for l in mini(v)..maxi(v) repeat
-               sum := sum + qelt(x,i,j) * v(l)
-             sum
-         w
-
-     if Row has shallowlyMutable then
-
-       v:Row * x:% ==
-         nrows(x) ^= #v =>
-           error "can't multiply vector v and matrix A if #rows A ^= #v"
-         w : Row := new(ncols x,0)
-         for j in minc(x)..maxc(x) for k in mini(w)..maxi(w) repeat
-           w.k :=
-             sum : R := 0
-             for i in minr(x)..maxr(x) for l in mini(v)..maxi(v) repeat
-               sum := sum + qelt(x,i,j) * v(l)
-             sum
-         w
-
-     if R has IntegralDomain then
-       x exquo a ==
-         ans := new(nrows x,ncols x,0)
-         for i in minr(x)..maxr(x) repeat
-           for j in minc(x)..maxc(x) repeat
-             entry :=
-               (r := (qelt(x,i,j) exquo a)) case "failed" =>
-                 return "failed"
-               r :: R
-             qsetelt_!(ans,i,j,entry)
-         ans
-
-     if R has Field then
-       x / r == map(#1 / r,x)
-
-       x:% ** n:Integer ==
-         not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
-         zero? n => scalarMatrix(nn,1)
-         positive? n => positivePower(x,n)
-         (xInv := inverse x) case "failed" =>
-           error "**: matrix must be invertible"
-         positivePower(xInv :: %,-n)
-
-@
-<<MATCAT.dotabb>>=
-"MATCAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MATCAT"];
-"MATCAT" -> "ARR2CAT"
-
-@
-<<MATCAT.dotfull>>=
-"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)" 
- [color=lightblue,href="bookvol10.2.pdf#nameddest=MATCAT"];
-"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)"
- ->
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
-
-@
-<<MATCAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)" 
- [color=lightblue];
-"MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)"
- ->
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
-
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
- [color=lightblue];
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
-    -> "HomogeneousAggregate(a:Type)"
-
-"HomogeneousAggregate(a:Type)" [color=lightblue];
-"HomogeneousAggregate(a:Type)" -> "Aggregate()"
-"HomogeneousAggregate(a:Type)" -> "Evalable(a:Type)"
-"HomogeneousAggregate(a:Type)" -> "SetCategory()"
-
-"Evalable(a:Type)" [color="#00EE00"];
-
-"SetCategory()" [color=lightblue];
-"SetCategory()" -> "BasicType()"
-"SetCategory()" -> "CoercibleTo(OutputForm)"
-
-"BasicType()" [color=lightblue];
-"BasicType()" -> "Category"
-
-"CoercibleTo(OutputForm)" [color=seagreen];
-"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
-
-"CoercibleTo(a:Type)" [color=lightblue];
-"CoercibleTo(a:Type)" -> "Category"
-
-"Aggregate()" [color=lightblue];
-"Aggregate()" -> "Type()"
-
-"Type()" [color=lightblue];
-"Type()" -> "Category"
-
-"Category" [color=lightblue];
-
+"KONVERT..." [color=lightblue];
+"MONOID..." [color=lightblue];
+"GROUP..." [color=lightblue];
+"ABELMON..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+"PDRING..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+"CHARNZ..." [color=lightblue];
+"INTDOM..." [color=lightblue];
+"FIELD..." [color=lightblue];
+"RETRACT..." [color=lightblue];
 }
 
 @
@@ -44319,6 +46368,457 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{RealClosedField}{RCFIELD}
+\pagepic{ps/v102realclosedfield.ps}{RCFIELD}{0.50}
+
+{\bf See:}\\
+\pagefrom{Algebra}{ALGEBRA}
+\pagefrom{CharacteristicZero}{CHARZ}
+\pagefrom{CommutativeRing}{COMRING}
+\pagefrom{Field}{FIELD}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{OrderedRing}{ORDRING}
+\pagefrom{RadicalCategory}{RADCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{RCFIELD}{0} &
+\cross{RCFIELD}{1} &
+\cross{RCFIELD}{abs} &
+\cross{RCFIELD}{allRootsOf} \\
+\cross{RCFIELD}{approximate} &
+\cross{RCFIELD}{associates?} &
+\cross{RCFIELD}{characteristic} &
+\cross{RCFIELD}{coerce} \\
+\cross{RCFIELD}{divide} &
+\cross{RCFIELD}{euclideanSize} &
+\cross{RCFIELD}{expressIdealMember} &
+\cross{RCFIELD}{exquo} \\
+\cross{RCFIELD}{extendedEuclidean} &
+\cross{RCFIELD}{factor} &
+\cross{RCFIELD}{gcd} &
+\cross{RCFIELD}{gcdPolynomial} \\
+\cross{RCFIELD}{hash} &
+\cross{RCFIELD}{inv} &
+\cross{RCFIELD}{latex} &
+\cross{RCFIELD}{lcm} \\
+\cross{RCFIELD}{mainDefiningPolynomial} &
+\cross{RCFIELD}{mainForm} &
+\cross{RCFIELD}{mainValue} &
+\cross{RCFIELD}{max} \\
+\cross{RCFIELD}{min} &
+\cross{RCFIELD}{multiEuclidean} &
+\cross{RCFIELD}{negative?} &
+\cross{RCFIELD}{nthRoot} \\
+\cross{RCFIELD}{one?} &
+\cross{RCFIELD}{positive?} &
+\cross{RCFIELD}{prime?} &
+\cross{RCFIELD}{principalIdeal} \\
+\cross{RCFIELD}{recip} &
+\cross{RCFIELD}{rename} &
+\cross{RCFIELD}{rename!} &
+\cross{RCFIELD}{retract} \\
+\cross{RCFIELD}{retractIfCan} &
+\cross{RCFIELD}{rootOf} &
+\cross{RCFIELD}{sample} &
+\cross{RCFIELD}{sign} \\
+\cross{RCFIELD}{sizeLess?} &
+\cross{RCFIELD}{sqrt} &
+\cross{RCFIELD}{squareFree} &
+\cross{RCFIELD}{squareFreePart} \\
+\cross{RCFIELD}{subtractIfCan} &
+\cross{RCFIELD}{unit?} &
+\cross{RCFIELD}{unitCanonical} &
+\cross{RCFIELD}{unitNormal} \\
+\cross{RCFIELD}{zero?} &
+\cross{RCFIELD}{?*?} &
+\cross{RCFIELD}{?**?} &
+\cross{RCFIELD}{?+?} \\
+\cross{RCFIELD}{?-?} &
+\cross{RCFIELD}{-?} &
+\cross{RCFIELD}{?/?} &
+\cross{RCFIELD}{?$<$?} \\
+\cross{RCFIELD}{?$<=$?} &
+\cross{RCFIELD}{?=?} &
+\cross{RCFIELD}{?$>$?} &
+\cross{RCFIELD}{?$>=$?} \\
+\cross{RCFIELD}{?\^{}?} &
+\cross{RCFIELD}{?\~{}=?} &
+\cross{RCFIELD}{?quo?} &
+\cross{RCFIELD}{?rem?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{RCFIELD}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{RCFIELD}{canonicalUnitNormal}}
+is true if we can choose a canonical representative for each class 
+of associate elements, that is {\tt associates?(a,b)} returns true 
+if and only if {\tt unitCanonical(a) = unitCanonical(b)}.
+\item {\bf \cross{RCFIELD}{canonicalsClosed}}
+is true if\\
+{\tt unitCanonical(a)*unitCanonical(b) = unitCanonical(a*b)}.
+\item {\bf \cross{RCFIELD}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{RCFIELD}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{RCFIELD}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item {\bf \cross{RCFIELD}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ allRootsOf : SparseUnivariatePolynomial % -> List %
+ approximate : (%,%) -> Fraction Integer
+ mainDefiningPolynomial :
+    % -> Union(SparseUnivariatePolynomial %,"failed")
+ mainForm : % -> Union(OutputForm,"failed")
+ mainValue : % -> Union(SparseUnivariatePolynomial %,"failed")
+ rename : (%,OutputForm) -> %         
+ rename! : (%,OutputForm) -> %
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ allRootsOf : Polynomial Integer -> List %
+ allRootsOf : Polynomial Fraction Integer -> List %
+ allRootsOf : Polynomial % -> List %
+ allRootsOf : SparseUnivariatePolynomial Integer -> List %
+ allRootsOf : SparseUnivariatePolynomial Fraction Integer -> List %
+ characteristic : () -> NonNegativeInteger
+ nthRoot : (%,Integer) -> %
+ rootOf :
+   (SparseUnivariatePolynomial %,PositiveInteger) ->
+      Union(%,"failed")
+ rootOf :
+   (SparseUnivariatePolynomial %,PositiveInteger,OutputForm) ->
+      Union(%,"failed")
+ sqrt : (%,NonNegativeInteger) -> %
+ sqrt : Integer -> %                  
+ sqrt : Fraction Integer -> %
+ sqrt : % -> %                        
+ ?**? : (%,Fraction Integer) -> %
+\end{verbatim}
+
+These exports come from \refto{CharacteristicZero}():
+\begin{verbatim}
+ 0 : () -> %                          
+ 1 : () -> %
+ coerce : Integer -> %                
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger
+ latex : % -> String
+ one? : % -> Boolean                  
+ recip : % -> Union(%,"failed")       
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?^? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?*? : (%,%) -> %                     
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (Integer,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?**? : (%,PositiveInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?=? : (%,%) -> Boolean               
+\end{verbatim}
+
+These exports come from \refto{OrderedRing}():
+\begin{verbatim}
+ abs : % -> %
+ coerce : Integer -> %                
+ max : (%,%) -> %                     
+ min : (%,%) -> %
+ negative? : % -> Boolean             
+ positive? : % -> Boolean
+ sign : % -> Integer                  
+ ?<? : (%,%) -> Boolean               
+ ?<=? : (%,%) -> Boolean
+ ?>? : (%,%) -> Boolean
+ ?>=? : (%,%) -> Boolean              
+ ?*? : (Integer,%) -> %
+\end{verbatim}
+
+These exports come from \refto{Field}():
+\begin{verbatim}
+ associates? : (%,%) -> Boolean       
+ coerce : % -> %                      
+ coerce : Fraction Integer -> %
+ coerce : Fraction Integer -> %
+ coerce : Fraction Integer -> %
+ divide : (%,%) -> Record(quotient: %,remainder: %)
+ euclideanSize : % -> NonNegativeInteger
+ expressIdealMember : (List %,%) -> Union(List %,"failed")
+ exquo : (%,%) -> Union(%,"failed")
+ extendedEuclidean : (%,%) -> Record(coef1: %,coef2: %,generator: %)
+ extendedEuclidean : (%,%,%) -> Union(Record(coef1: %,coef2: %),"failed")
+ factor : % -> Factored %             
+ gcd : (%,%) -> %
+ gcd : List % -> %                    
+ gcdPolynomial :
+   (SparseUnivariatePolynomial %,
+    SparseUnivariatePolynomial %) ->
+       SparseUnivariatePolynomial %
+ inv : % -> %                         
+ lcm : (%,%) -> %                     
+ lcm : List % -> %
+ multiEuclidean : (List %,%) -> Union(List %,"failed")
+ prime? : % -> Boolean                
+ principalIdeal : List % -> Record(coef: List %,generator: %)
+ sizeLess? : (%,%) -> Boolean
+ squareFree : % -> Factored %
+ squareFreePart : % -> %              
+ unit? : % -> Boolean
+ unitCanonical : % -> %               
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %)
+ ?/? : (%,%) -> %
+ ?*? : (Fraction Integer,%) -> %
+ ?*? : (Fraction Integer,%) -> %
+ ?*? : (%,Fraction Integer) -> %      
+ ?*? : (%,Fraction Integer) -> %      
+ ?**? : (%,Integer) -> %              
+ ?^? : (%,Integer) -> %
+ ?quo? : (%,%) -> %
+ ?rem? : (%,%) -> %
+\end{verbatim}
+
+These exports come from \refto{FullyRetractableTo}(Fraction(Integer)):
+\begin{verbatim}
+ retract : % -> Fraction Integer      
+ retract : % -> Fraction Integer 
+   if Fraction Integer has RETRACT FRAC INT
+ retract : % -> Integer if Fraction Integer has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed")
+ retractIfCan : % -> Union(Fraction Integer,"failed") 
+   if Fraction Integer has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") 
+   if Fraction Integer has RETRACT INT
+\end{verbatim}
+
+These exports come from \refto{Algebra}(Integer):
+\begin{verbatim}
+ ?*? : (%,Integer) -> %               
+\end{verbatim}
+
+<<category RCFIELD RealClosedField>>=
+)abbrev category RCFIELD RealClosedField
+++ Author: Renaud Rioboo
+++ Date Created: may 1993
+++ Date Last Updated: January 2004
+++ Basic Functions: provides computations with generic real roots of 
+++                  polynomials 
+++ Related Constructors: SimpleOrderedAlgebraicExtension, RealClosure
+++ Also See: 
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References: 
+++ Description:
+++ \axiomType{RealClosedField} provides common acces
+++ functions for all real closed fields.
+RealClosedField : Category == PUB where
+
+    E ==> OutputForm
+    SUP ==> SparseUnivariatePolynomial
+    OFIELD ==> Join(OrderedRing,Field)
+    PME ==> SUP($)
+    N ==> NonNegativeInteger
+    PI ==> PositiveInteger
+    RN ==> Fraction(Integer)
+    Z  ==> Integer
+    POLY ==> Polynomial
+    PACK ==> SparseUnivariatePolynomialFunctions2
+
+    PUB == Join(CharacteristicZero,
+                OrderedRing,
+                CommutativeRing,
+                Field,
+                FullyRetractableTo(Fraction(Integer)),
+                Algebra Integer,
+                Algebra(Fraction(Integer)),
+                RadicalCategory) with
+
+        mainForm :   $ -> Union(E,"failed")
+             ++ \axiom{mainForm(x)} is the main algebraic quantity name of 
+             ++ \axiom{x}
+
+        mainDefiningPolynomial :   $ -> Union(PME,"failed")
+             ++ \axiom{mainDefiningPolynomial(x)} is the defining 
+             ++ polynomial for the main algebraic quantity of \axiom{x}
+
+        mainValue :   $ -> Union(PME,"failed")
+             ++ \axiom{mainValue(x)} is the expression of \axiom{x} in terms
+             ++ of \axiom{SparseUnivariatePolynomial($)} 
+
+        rootOf:          (PME,PI,E)           -> Union($,"failed")
+             ++ \axiom{rootOf(pol,n,name)} creates the nth root for the order
+             ++ of \axiom{pol} and names it \axiom{name}
+
+        rootOf:          (PME,PI)             -> Union($,"failed")
+             ++ \axiom{rootOf(pol,n)} creates the nth root for the order
+             ++ of \axiom{pol} and gives it unique name
+
+        allRootsOf:       PME                ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        allRootsOf:       (SUP(RN))          ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        allRootsOf:       (SUP(Z))          ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        allRootsOf:       (POLY($))         ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        allRootsOf:       (POLY(RN))        ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        allRootsOf:       (POLY(Z))         ->  List $
+             ++ \axiom{allRootsOf(pol)} creates all the roots
+             ++ of \axiom{pol} naming each uniquely
+
+        sqrt:            ($,N)                ->     $
+             ++ \axiom{sqrt(x,n)} is \axiom{x ** (1/n)}
+
+        sqrt:              $                  ->     $
+             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+        sqrt:             RN                  ->     $
+             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+        sqrt:              Z                  ->     $
+             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+        rename! :        ($,E)                ->     $
+             ++ \axiom{rename!(x,name)} changes the way \axiom{x} is printed
+
+        rename :         ($,E)                ->     $
+             ++ \axiom{rename(x,name)} gives a new number that prints as name
+
+        approximate:       ($,$) -> RN
+              ++ \axiom{approximate(n,p)} gives an approximation of \axiom{n}
+              ++ that has precision \axiom{p}
+
+      add
+
+        sqrt(a:$):$ == sqrt(a,2)
+
+        sqrt(a:RN):$ == sqrt(a::$,2)
+
+        sqrt(a:Z):$ == sqrt(a::$,2)
+
+        characteristic() == 0
+
+        rootOf(pol,n,o) == 
+          r := rootOf(pol,n)
+          r case "failed" => "failed"
+          rename!(r,o)
+
+        rootOf(pol,n) ==
+          liste:List($):= allRootsOf(pol)
+          # liste > n => "failed"
+          liste.n
+
+
+        sqrt(x,n) ==
+          n = 0 => 1
+          n = 1 => x
+          zero?(x) => 0
+          one?(x) => 1 
+          if odd?(n)
+          then
+            r := rootOf(monomial(1,n) - (x :: PME), 1)
+          else
+            r := rootOf(monomial(1,n) - (x :: PME), 2)
+          r case "failed" => error "no roots"
+          n = 2 => rename(r,root(x::E)$E)
+          rename(r,root(x :: E, n :: E)$E)
+
+        (x : $) ** (rn : RN) == sqrt(x**numer(rn),denom(rn)::N)
+
+        nthRoot(x, n) == 
+          zero?(n) => x
+          negative?(n) => inv(sqrt(x,(-n) :: N))
+          sqrt(x,n :: N)
+
+        allRootsOf(p:SUP(RN)) == allRootsOf(map(#1 :: $ ,p)$PACK(RN,$))
+
+        allRootsOf(p:SUP(Z)) == allRootsOf(map(#1 :: $ ,p)$PACK(Z,$))
+
+        allRootsOf(p:POLY($)) == allRootsOf(univariate(p))
+
+        allRootsOf(p:POLY(RN)) == allRootsOf(univariate(p))
+
+        allRootsOf(p:POLY(Z)) == allRootsOf(univariate(p))
+
+@
+<<RCFIELD.dotabb>>=
+"RCFIELD"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RCFIELD"];
+"RCFIELD" -> "ALGEBRA"
+"RCFIELD" -> "CHARZ"
+"RCFIELD" -> "COMRING"
+"RCFIELD" -> "FIELD"
+"RCFIELD" -> "FRETRCT"
+"RCFIELD" -> "ORDRING"
+"RCFIELD" -> "RADCAT"
+
+@
+<<RCFIELD.dotfull>>=
+"RealClosedField()" 
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RCFIELD"];
+"RealClosedField()" -> "Algebra(Integer)"
+"RealClosedField()" -> "Algebra(Fraction(Integer))"
+"RealClosedField()" -> "CharacteristicZero()"
+"RealClosedField()" -> "CommutativeRing()"
+"RealClosedField()" -> "Field()"
+"RealClosedField()" -> "FullyRetractableTo(Fraction(Integer))"
+"RealClosedField()" -> "OrderedRing()"
+"RealClosedField()" -> "RadicalCategory()"
+
+@
+<<RCFIELD.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"RealClosedField()" [color=lightblue];
+"RealClosedField()" -> "ALGEBRA..."
+"RealClosedField()" -> "CHARZ..."
+"RealClosedField()" -> "COMRING..."
+"RealClosedField()" -> "FIELD..."
+"RealClosedField()" -> "FRETRCT..."
+"RealClosedField()" -> "ORDRING..."
+"RealClosedField()" -> "RADCAT..."
+
+"ALGEBRA..." [color=lightblue];
+"CHARZ..." [color=lightblue];
+"COMRING..." [color=lightblue];
+"FIELD..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+"ORDRING..." [color=lightblue];
+"RADCAT..." [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{RealNumberSystem}{RNS}
 \pagepic{ps/v102realnumbersystem.ps}{RNS}{0.50}
 
@@ -46928,6 +49428,7 @@ digraph pic {
 \pagepic{ps/v102univariatepuiseuxseriescategory.ps}{UPXSCAT}{0.50}
 
 {\bf See:}\\
+\pageto{UnivariatePuiseuxSeriesConstructorCategory}{UPXSCCA}
 \pagefrom{TranscendentalFunctionCategory}{TRANFUN}
 \pagefrom{Field}{FIELD}
 \pagefrom{RadicalCategory}{RADCAT}
@@ -47141,8 +49642,8 @@ where Coef:Ring and RN:Fraction(Integer):
  map : ((Coef -> Coef),%) -> %        
  monomial : (%,List SingletonAsOrderedSet,List Fraction Integer) -> %
  monomial : (Coef,Fraction Integer) -> %
- monomial? : % -> Boolean
  monomial : (%,SingletonAsOrderedSet,Fraction Integer) -> %
+ monomial? : % -> Boolean
  multiplyExponents : (%,PositiveInteger) -> %
  one? : % -> Boolean                  
  order : (%,Fraction Integer) -> Fraction Integer
@@ -47330,7 +49831,7 @@ UnivariatePuiseuxSeriesCategory(Coef): Category == Definition where
 "UPXSCAT" -> "UPSCAT"
 
 @
-<<UPXSCAT.dotabb>>=
+<<UPXSCAT.dotfull>>=
 "UnivariatePuiseuxSeriesCategory(a:Ring)" 
  [color=lightblue,href="bookvol10.2.pdf#nameddest=UPXSCAT"];
 "UnivariatePuiseuxSeriesCategory(a:Ring)" ->
@@ -48370,7 +50871,7 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 18}
+\chapter{Category Layer 17}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{AlgebraicallyClosedFunctionSpace}{ACFS}
 \pagepic{ps/v102algebraicallyclosedfunctionspace.ps}{ACFS}{0.45}
@@ -48920,6 +51421,7 @@ digraph pic {
 "RadicalCategory()" -> "Category"
 
 "Category" [color=lightblue];
+
 "FunctionSpace(a:OrderedSet)" [color=lightblue];
 "FunctionSpace(a:OrderedSet)" -> "ExpressionSpace()"
 "FunctionSpace(a:OrderedSet)" -> "RETRACT..."
@@ -51067,7 +53569,468 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 19}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{UnivariatePuiseuxSeriesConstructorCategory}{UPXSCCA}
+\pagepic{ps/v102univariatepuiseuxseriesconstructorcategory.ps}{UPXSCCA}{0.50}
+
+{\bf See:}\\
+\pagefrom{RetractableTo}{RETRACT}
+\pagefrom{UnivariatePuiseuxSeriesCategory}{UPXSCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{UPXSCCA}{0} &
+\cross{UPXSCCA}{1} &
+\cross{UPXSCCA}{acos} &
+\cross{UPXSCCA}{acosh} \\
+\cross{UPXSCCA}{acot} &
+\cross{UPXSCCA}{acoth} &
+\cross{UPXSCCA}{acsc} &
+\cross{UPXSCCA}{acsch} \\
+\cross{UPXSCCA}{approximate} &
+\cross{UPXSCCA}{asec} &
+\cross{UPXSCCA}{asech} &
+\cross{UPXSCCA}{asin} \\
+\cross{UPXSCCA}{asinh} &
+\cross{UPXSCCA}{associates?} &
+\cross{UPXSCCA}{atan} &
+\cross{UPXSCCA}{atanh} \\
+\cross{UPXSCCA}{center} &
+\cross{UPXSCCA}{characteristic} &
+\cross{UPXSCCA}{charthRoot} &
+\cross{UPXSCCA}{coefficient} \\
+\cross{UPXSCCA}{coerce} &
+\cross{UPXSCCA}{complete} &
+\cross{UPXSCCA}{cos} &
+\cross{UPXSCCA}{cosh} \\
+\cross{UPXSCCA}{cot} &
+\cross{UPXSCCA}{coth} &
+\cross{UPXSCCA}{csc} &
+\cross{UPXSCCA}{csch} \\
+\cross{UPXSCCA}{D} &
+\cross{UPXSCCA}{degree} &
+\cross{UPXSCCA}{differentiate} &
+\cross{UPXSCCA}{divide} \\
+\cross{UPXSCCA}{euclideanSize} &
+\cross{UPXSCCA}{eval} &
+\cross{UPXSCCA}{exp} &
+\cross{UPXSCCA}{expressIdealMember} \\
+\cross{UPXSCCA}{exquo} &
+\cross{UPXSCCA}{extend} &
+\cross{UPXSCCA}{extendedEuclidean} &
+\cross{UPXSCCA}{factor} \\
+\cross{UPXSCCA}{gcd} &
+\cross{UPXSCCA}{gcdPolynomial} &
+\cross{UPXSCCA}{hash} &
+\cross{UPXSCCA}{integrate} \\
+\cross{UPXSCCA}{inv} &
+\cross{UPXSCCA}{latex} &
+\cross{UPXSCCA}{laurent} &
+\cross{UPXSCCA}{laurentIfCan} \\
+\cross{UPXSCCA}{laurentRep} &
+\cross{UPXSCCA}{lcm} &
+\cross{UPXSCCA}{leadingCoefficient} &
+\cross{UPXSCCA}{leadingMonomial} \\
+\cross{UPXSCCA}{log} &
+\cross{UPXSCCA}{map} &
+\cross{UPXSCCA}{monomial} &
+\cross{UPXSCCA}{monomial?} \\
+\cross{UPXSCCA}{multiEuclidean} &
+\cross{UPXSCCA}{multiplyExponents} &
+\cross{UPXSCCA}{nthRoot} &
+\cross{UPXSCCA}{one?} \\
+\cross{UPXSCCA}{order} &
+\cross{UPXSCCA}{pi} &
+\cross{UPXSCCA}{pole?} &
+\cross{UPXSCCA}{prime?} \\
+\cross{UPXSCCA}{principalIdeal} &
+\cross{UPXSCCA}{puiseux} &
+\cross{UPXSCCA}{rationalPower} &
+\cross{UPXSCCA}{recip} \\
+\cross{UPXSCCA}{reductum} &
+\cross{UPXSCCA}{retract} &
+\cross{UPXSCCA}{retractIfCan} &
+\cross{UPXSCCA}{sample} \\
+\cross{UPXSCCA}{sec} &
+\cross{UPXSCCA}{sech} &
+\cross{UPXSCCA}{series} &
+\cross{UPXSCCA}{sin} \\
+\cross{UPXSCCA}{sinh} &
+\cross{UPXSCCA}{sizeLess?} &
+\cross{UPXSCCA}{sqrt} &
+\cross{UPXSCCA}{squareFree} \\
+\cross{UPXSCCA}{squareFreePart} &
+\cross{UPXSCCA}{subtractIfCan} &
+\cross{UPXSCCA}{tan} &
+\cross{UPXSCCA}{tanh} \\
+\cross{UPXSCCA}{terms} &
+\cross{UPXSCCA}{truncate} &
+\cross{UPXSCCA}{unit?} &
+\cross{UPXSCCA}{unitCanonical} \\
+\cross{UPXSCCA}{unitNormal} &
+\cross{UPXSCCA}{variable} &
+\cross{UPXSCCA}{variables} &
+\cross{UPXSCCA}{zero?} \\
+\cross{UPXSCCA}{?.?} &
+\cross{UPXSCCA}{?*?} &
+\cross{UPXSCCA}{?**?} &
+\cross{UPXSCCA}{?+?} \\
+\cross{UPXSCCA}{?-?} &
+\cross{UPXSCCA}{-?} &
+\cross{UPXSCCA}{?=?} &
+\cross{UPXSCCA}{?\^{}?} \\
+\cross{UPXSCCA}{?\~{}=?} &
+\cross{UPXSCCA}{?/?} &
+\cross{UPXSCCA}{?quo?} &
+\cross{UPXSCCA}{?rem?} \\
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{UPXSCCA}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{UPXSCCA}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{UPXSCCA}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item if \#1 has Field then canonicalsClosed where
+\item {\bf \cross{UPXSCCA}{canonicalsClosed}}
+is true if\\
+{\tt unitCanonical(a)*unitCanonical(b) = unitCanonical(a*b)}.
+\item if \#1 has Field then canonicalUnitNormal where
+{\bf \cross{UPXSCCA}{canonicalUnitNormal}}
+is true if we can choose a canonical representative for each class 
+of associate elements, that is {\tt associates?(a,b)} returns true 
+if and only if {\tt unitCanonical(a) = unitCanonical(b)}.
+\item if \#1 has IntegralDomain then noZeroDivisors where
+{\bf \cross{UPXSCCA}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item if \#1 has CommutativeRing then commututive(``*'') where
+{\bf \cross{UPXSCCA}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ coerce : ULS -> %                    
+ degree : % -> Fraction Integer       
+ laurent : % -> ULS
+ laurentIfCan : % -> Union(ULS,"failed")
+ laurentRep : % -> ULS                
+ puiseux : (Fraction Integer,ULS) -> %
+ rationalPower : % -> Fraction Integer
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ retract : % -> ULS                   
+ retractIfCan : % -> Union(ULS,"failed")
+ zero? : % -> Boolean
+\end{verbatim}
+
+These exports come from \refto{UnivariatePuiseuxSeriesCategory}(Coef:Ring):
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ approximate : (%,Fraction Integer) -> Coef 
+   if Coef has **: (Coef,Fraction Integer) -> Coef 
+   and Coef has coerce: Symbol -> Coef
+ associates? : (%,%) -> Boolean if Coef has INTDOM
+ acos : % -> % if Coef has ALGEBRA FRAC INT
+ acosh : % -> % if Coef has ALGEBRA FRAC INT
+ acot : % -> % if Coef has ALGEBRA FRAC INT
+ acoth : % -> % if Coef has ALGEBRA FRAC INT
+ acsc : % -> % if Coef has ALGEBRA FRAC INT
+ acsch : % -> % if Coef has ALGEBRA FRAC INT
+ asec : % -> % if Coef has ALGEBRA FRAC INT
+ asech : % -> % if Coef has ALGEBRA FRAC INT
+ asin : % -> % if Coef has ALGEBRA FRAC INT
+ asinh : % -> % if Coef has ALGEBRA FRAC INT
+ atan : % -> % if Coef has ALGEBRA FRAC INT
+ atanh : % -> % if Coef has ALGEBRA FRAC INT
+ center : % -> Coef
+ characteristic : () -> NonNegativeInteger
+ charthRoot : % -> Union(%,"failed") if Coef has CHARNZ
+ coefficient : (%,Fraction Integer) -> Coef
+ coerce : % -> % if Coef has INTDOM
+ coerce : Fraction Integer -> % if Coef has ALGEBRA FRAC INT
+ coerce : Coef -> % if Coef has COMRING
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ complete : % -> %
+ cos : % -> % if Coef has ALGEBRA FRAC INT
+ cosh : % -> % if Coef has ALGEBRA FRAC INT
+ cot : % -> % if Coef has ALGEBRA FRAC INT
+ coth : % -> % if Coef has ALGEBRA FRAC INT
+ csc : % -> % if Coef has ALGEBRA FRAC INT
+ csch : % -> % if Coef has ALGEBRA FRAC INT
+ D : % -> % if Coef has *: (Fraction Integer,Coef) -> Coef
+ D : (%,NonNegativeInteger) -> % 
+   if Coef has *: (Fraction Integer,Coef) -> Coef
+ D : (%,Symbol) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ D : (%,List Symbol) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ D : (%,Symbol,NonNegativeInteger) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ D : (%,List Symbol,List NonNegativeInteger) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : (%,Symbol) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : (%,List Symbol) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : (%,Symbol,NonNegativeInteger) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % 
+   if Coef has PDRING SYMBOL 
+   and Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : % -> % if Coef has *: (Fraction Integer,Coef) -> Coef
+ differentiate : (%,NonNegativeInteger) -> % 
+   if Coef has *: (Fraction Integer,Coef) -> Coef
+ divide : (%,%) -> Record(quotient: %,remainder: %) if Coef has FIELD
+ euclideanSize : % -> NonNegativeInteger if Coef has FIELD
+ eval : (%,Coef) -> Stream Coef 
+   if Coef has **: (Coef,Fraction Integer) -> Coef
+ exp : % -> % if Coef has ALGEBRA FRAC INT
+ expressIdealMember : (List %,%) -> Union(List %,"failed") 
+   if Coef has FIELD
+ extendedEuclidean : (%,%) -> Record(coef1: %,coef2: %,generator: %) 
+   if Coef has FIELD
+ extendedEuclidean : (%,%,%) -> Union(Record(coef1: %,coef2: %),"failed") 
+   if Coef has FIELD
+ exquo : (%,%) -> Union(%,"failed") if Coef has INTDOM
+ extend : (%,Fraction Integer) -> %
+ factor : % -> Factored % if Coef has FIELD
+ gcd : (%,%) -> % if Coef has FIELD
+ gcd : List % -> % if Coef has FIELD
+ gcdPolynomial :
+   (SparseUnivariatePolynomial %,
+    SparseUnivariatePolynomial %) ->
+      SparseUnivariatePolynomial % 
+        if Coef has FIELD
+ hash : % -> SingleInteger
+ integrate : (%,Symbol) -> % 
+   if Coef has ACFS INT 
+   and Coef has PRIMCAT 
+   and Coef has TRANFUN 
+   and Coef has ALGEBRA FRAC INT 
+   or Coef has variables: Coef -> List Symbol 
+   and Coef has integrate: (Coef,Symbol) -> Coef 
+   and Coef has ALGEBRA FRAC INT
+ integrate : % -> % if Coef has ALGEBRA FRAC INT
+ inv : % -> % if Coef has FIELD
+ latex : % -> String                  
+ lcm : (%,%) -> % if Coef has FIELD
+ lcm : List % -> % if Coef has FIELD
+ leadingCoefficient : % -> Coef
+ leadingMonomial : % -> %             
+ log : % -> % if Coef has ALGEBRA FRAC INT
+ map : ((Coef -> Coef),%) -> %
+ monomial : (%,List SingletonAsOrderedSet,List Fraction Integer) -> %
+ monomial : (%,SingletonAsOrderedSet,Fraction Integer) -> %
+ monomial : (Coef,Fraction Integer) -> %
+ monomial? : % -> Boolean             
+ multiEuclidean : (List %,%) -> Union(List %,"failed") if Coef has FIELD
+ multiplyExponents : (%,PositiveInteger) -> %
+ multiplyExponents : (%,Fraction Integer) -> %
+ nthRoot : (%,Integer) -> % if Coef has ALGEBRA FRAC INT
+ one? : % -> Boolean
+ order : (%,Fraction Integer) -> Fraction Integer
+ order : % -> Fraction Integer        
+ pi : () -> % if Coef has ALGEBRA FRAC INT
+ pole? : % -> Boolean
+ prime? : % -> Boolean if Coef has FIELD
+ principalIdeal : List % -> Record(coef: List %,generator: %) 
+   if Coef has FIELD
+ recip : % -> Union(%,"failed")       
+ reductum : % -> %
+ sample : () -> %
+ sec : % -> % if Coef has ALGEBRA FRAC INT
+ sech : % -> % if Coef has ALGEBRA FRAC INT
+ series :
+   (NonNegativeInteger,Stream Record(k: Fraction Integer,c: Coef)) -> %
+ sin : % -> % if Coef has ALGEBRA FRAC INT
+ sinh : % -> % if Coef has ALGEBRA FRAC INT
+ sizeLess? : (%,%) -> Boolean if Coef has FIELD
+ sqrt : % -> % if Coef has ALGEBRA FRAC INT
+ squareFree : % -> Factored % if Coef has FIELD
+ squareFreePart : % -> % if Coef has FIELD
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ tan : % -> % if Coef has ALGEBRA FRAC INT
+ tanh : % -> % if Coef has ALGEBRA FRAC INT
+ terms : % -> Stream Record(k: Fraction Integer,c: Coef)
+ truncate : (%,Fraction Integer,Fraction Integer) -> %
+ truncate : (%,Fraction Integer) -> %
+ unit? : % -> Boolean if Coef has INTDOM
+ unitCanonical : % -> % if Coef has INTDOM
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) 
+   if Coef has INTDOM
+ variable : % -> Symbol               
+ variables : % -> List SingletonAsOrderedSet
+ ?**? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?**? : (%,Integer) -> % if Coef has FIELD
+ ?^? : (%,Integer) -> % if Coef has FIELD
+ ?/? : (%,%) -> % if Coef has FIELD
+ ?**? : (%,%) -> % if Coef has ALGEBRA FRAC INT
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (Coef,%) -> %                  
+ ?*? : (%,Coef) -> %
+ ?*? : (%,Fraction Integer) -> % if Coef has ALGEBRA FRAC INT
+ ?*? : (Fraction Integer,%) -> % if Coef has ALGEBRA FRAC INT
+ ?/? : (%,Coef) -> % if Coef has FIELD
+ -? : % -> %                          
+ ?.? : (%,%) -> % if Fraction Integer has SGROUP
+ ?.? : (%,Fraction Integer) -> Coef
+ ?quo? : (%,%) -> % if Coef has FIELD
+ ?rem? : (%,%) -> % if Coef has FIELD
+\end{verbatim}
+
+<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>=
+)abbrev category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 6 February 1990
+++ Date Last Updated: 22 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux, Laurent
+++ Examples:
+++ References:
+++ Description:
+++   This is a category of univariate Puiseux series constructed
+++   from univariate Laurent series.  A Puiseux series is represented
+++   by a pair \spad{[r,f(x)]}, where r is a positive rational number and
+++   \spad{f(x)} is a Laurent series.  This pair represents the Puiseux
+++   series \spad{f(x^r)}.
+UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS):_
+ Category == Definition where
+  Coef : Ring
+  ULS  : UnivariateLaurentSeriesCategory Coef
+  I  ==> Integer
+  RN ==> Fraction Integer
+
+  Definition ==> Join(UnivariatePuiseuxSeriesCategory(Coef),_
+                      RetractableTo ULS) with
+    puiseux: (RN,ULS) -> %
+      ++ \spad{puiseux(r,f(x))} returns \spad{f(x^r)}.
+    rationalPower: % -> RN
+      ++ \spad{rationalPower(f(x))} returns r where the Puiseux series
+      ++ \spad{f(x) = g(x^r)}.
+    laurentRep  : % -> ULS
+      ++ \spad{laurentRep(f(x))} returns \spad{g(x)} where the Puiseux series
+      ++ \spad{f(x) = g(x^r)} is represented by \spad{[r,g(x)]}.
+    degree: % -> RN
+      ++ \spad{degree(f(x))} returns the degree of the leading term of the
+      ++ Puiseux series \spad{f(x)}, which may have zero as a coefficient.
+    coerce: ULS -> %
+      ++ \spad{coerce(f(x))} converts the Laurent series \spad{f(x)} to a
+      ++ Puiseux series.
+    laurent: % -> ULS
+      ++ \spad{laurent(f(x))} converts the Puiseux series \spad{f(x)} to a
+      ++ Laurent series if possible. Error: if this is not possible.
+    laurentIfCan: % -> Union(ULS,"failed")
+      ++ \spad{laurentIfCan(f(x))} converts the Puiseux series \spad{f(x)}
+      ++ to a Laurent series if possible.
+      ++ If this is not possible, "failed" is returned.
+
+   add
+
+     zero? x == zero? laurentRep x
+
+     retract(x:%):ULS == laurent x
+
+     retractIfCan(x:%):Union(ULS,"failed") == laurentIfCan x
+
+@
+<<UPXSCCA.dotabb>>=
+"UPXSCCA"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UPXSCCA"];
+"UPXSCCA" -> "RETRACT"
+"UPXSCCA" -> "UPXSCAT"
+
+@
+<<UPXSCCA.dotfull>>=
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UPXSCCA"];
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+  -> "RetractableTo(UnivariatePuiseuxSeriesCategory(Ring))"
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+  -> "UnivariatePuiseuxSeriesCategory(a:Ring)"
+
+@
+<<UPXSCCA.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=UPXSCCA"];
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+  -> "RETRACT..."
+"UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))"
+  -> "UnivariatePuiseuxSeriesCategory(a:Ring)"
+
+"UnivariatePuiseuxSeriesCategory(a:Ring)" [color=lightblue];
+"UnivariatePuiseuxSeriesCategory(a:Ring)" ->
+    "UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))"
+"UnivariatePuiseuxSeriesCategory(a:Ring)" ->
+    "TRANFUN..."
+"UnivariatePuiseuxSeriesCategory(a:Ring)" ->
+    "FIELD..."
+"UnivariatePuiseuxSeriesCategory(a:Ring)" ->
+    "RADCAT..."
+
+"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" [color=seagreen];
+"UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))" ->
+    "UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)"
+
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" 
+ [color=lightblue];
+"UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)" ->
+ "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+ [color=seagreen];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)"
+  -> "PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)"
+ [color=lightblue];
+"PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)" ->
+    "AMR..."
+
+"RETRACT..." [color=lightblue];
+"TRANFUN..." [color=lightblue];
+"FIELD..." [color=lightblue];
+"RADCAT..." [color=lightblue];
+"AMR..." [color=lightblue];
+}
+
+@
+\chapter{Category Layer 18}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FiniteAlgebraicExtensionField}{FAXF}
 \pagepic{ps/v102finitealgebraicextensionfield.ps}{FAXF}{0.75}
@@ -51914,15 +54877,6 @@ where R:CommutativeRing and UP:UnivariatePolynomialCategory(a)
  ?^? : (%,NonNegativeInteger) -> %
 \end{verbatim}
 
-These exports come from \refto{CommutativeRing}()
-\begin{verbatim}
-\end{verbatim}
-
-These exports come from \refto{ConvertibleTo}\\
-where UP:UnivariatePolynomialCategory(CommutativeRing)
-\begin{verbatim}
-\end{verbatim}
-
 These exports come from \refto{FullyRetractableTo}(R)\\
 where R:CommutativeRing
 \begin{verbatim}
@@ -52217,7 +55171,942 @@ digraph pic {
 }
 
 @
-\chapter{Category Layer 20}
+\chapter{Category Layer 19}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{ComplexCategory}{COMPCAT}
+\pagepic{ps/v102complexcategory.ps}{COMPCAT}{0.50}
+
+{\bf See:}\\
+\pagefrom{CommutativeRing}{COMRING}
+\pagefrom{DifferentialExtension}{DIFEXT}
+\pagefrom{FullyEvalableOver}{FEVALAB}
+\pagefrom{FullyPatternMatchable}{FPATMAB}
+\pagefrom{FullyRetractableTo}{FRETRCT}
+\pagefrom{MonogenicAlgebra}{MONOGEN}
+\pagefrom{Patternable}{PATAB}
+\pagefrom{FullyLinearlyExplicitRingOver}{FLINEXP}
+
+{\bf Exports:}\\
+\begin{tabular}{lll}
+\cross{COMPCAT}{0} &
+\cross{COMPCAT}{1} &
+\cross{COMPCAT}{abs} \\
+\cross{COMPCAT}{acos} &
+\cross{COMPCAT}{acosh} &
+\cross{COMPCAT}{acot} \\
+\cross{COMPCAT}{acoth} &
+\cross{COMPCAT}{acsc} &
+\cross{COMPCAT}{acsch} \\
+\cross{COMPCAT}{argument} &
+\cross{COMPCAT}{asec} &
+\cross{COMPCAT}{asech} \\
+\cross{COMPCAT}{asin} &
+\cross{COMPCAT}{asinh} &
+\cross{COMPCAT}{associates?} \\
+\cross{COMPCAT}{atan} &
+\cross{COMPCAT}{atanh} &
+\cross{COMPCAT}{basis} \\
+\cross{COMPCAT}{characteristic} &
+\cross{COMPCAT}{characteristicPolynomial} &
+\cross{COMPCAT}{charthRoot} \\
+\cross{COMPCAT}{coerce} &
+\cross{COMPCAT}{complex} &
+\cross{COMPCAT}{conditionP} \\
+\cross{COMPCAT}{conjugate} &
+\cross{COMPCAT}{convert} &
+\cross{COMPCAT}{coordinates} \\
+\cross{COMPCAT}{cos} &
+\cross{COMPCAT}{cosh} &
+\cross{COMPCAT}{cot} \\
+\cross{COMPCAT}{coth} &
+\cross{COMPCAT}{createPrimitiveElement} &
+\cross{COMPCAT}{csc} \\
+\cross{COMPCAT}{csch} &
+\cross{COMPCAT}{D} &
+\cross{COMPCAT}{definingPolynomial} \\
+\cross{COMPCAT}{derivationCoordinates} &
+\cross{COMPCAT}{differentiate} &
+\cross{COMPCAT}{discreteLog} \\
+\cross{COMPCAT}{discriminant} &
+\cross{COMPCAT}{divide} &
+\cross{COMPCAT}{euclideanSize} \\
+\cross{COMPCAT}{eval} &
+\cross{COMPCAT}{exp} &
+\cross{COMPCAT}{expressIdealMember} \\
+\cross{COMPCAT}{exquo} &
+\cross{COMPCAT}{extendedEuclidean} &
+\cross{COMPCAT}{factor} \\
+\cross{COMPCAT}{factorPolynomial} &
+\cross{COMPCAT}{factorSquareFreePolynomial} &
+\cross{COMPCAT}{factorsOfCyclicGroupSize} \\
+\cross{COMPCAT}{gcd} &
+\cross{COMPCAT}{gcdPolynomial} &
+\cross{COMPCAT}{generator} \\
+\cross{COMPCAT}{hash} &
+\cross{COMPCAT}{imag} &
+\cross{COMPCAT}{imaginary} \\
+\cross{COMPCAT}{index} &
+\cross{COMPCAT}{init} &
+\cross{COMPCAT}{inv} \\
+\cross{COMPCAT}{latex} &
+\cross{COMPCAT}{lcm} &
+\cross{COMPCAT}{lift} \\
+\cross{COMPCAT}{log} &
+\cross{COMPCAT}{lookup} &
+\cross{COMPCAT}{map} \\
+\cross{COMPCAT}{max} &
+\cross{COMPCAT}{min} &
+\cross{COMPCAT}{minimalPolynomial} \\
+\cross{COMPCAT}{multiEuclidean} &
+\cross{COMPCAT}{nextItem} &
+\cross{COMPCAT}{norm} \\
+\cross{COMPCAT}{nthRoot} &
+\cross{COMPCAT}{one?} &
+\cross{COMPCAT}{order} \\
+\cross{COMPCAT}{patternMatch} &
+\cross{COMPCAT}{pi} &
+\cross{COMPCAT}{polarCoordinates} \\
+\cross{COMPCAT}{prime?} &
+\cross{COMPCAT}{primeFrobenius} &
+\cross{COMPCAT}{primitive?} \\
+\cross{COMPCAT}{primitiveElement} &
+\cross{COMPCAT}{principalIdeal} &
+\cross{COMPCAT}{random} \\
+\cross{COMPCAT}{rank} &
+\cross{COMPCAT}{rational} &
+\cross{COMPCAT}{rational?} \\
+\cross{COMPCAT}{rationalIfCan} &
+\cross{COMPCAT}{real} &
+\cross{COMPCAT}{recip} \\
+\cross{COMPCAT}{reduce} &
+\cross{COMPCAT}{reducedSystem} &
+\cross{COMPCAT}{regularRepresentation} \\
+\cross{COMPCAT}{represents} &
+\cross{COMPCAT}{representationType} &
+\cross{COMPCAT}{represents} \\
+\cross{COMPCAT}{retract} &
+\cross{COMPCAT}{retractIfCan} &
+\cross{COMPCAT}{sample} \\
+\cross{COMPCAT}{sec} &
+\cross{COMPCAT}{sech} &
+\cross{COMPCAT}{sin} \\
+\cross{COMPCAT}{sinh} &
+\cross{COMPCAT}{size} &
+\cross{COMPCAT}{sizeLess?} \\
+\cross{COMPCAT}{solveLinearPolynomialEquation} &
+\cross{COMPCAT}{sqrt} &
+\cross{COMPCAT}{squareFree} \\
+\cross{COMPCAT}{squareFreePart} &
+\cross{COMPCAT}{squareFreePolynomial} &
+\cross{COMPCAT}{subtractIfCan} \\
+\cross{COMPCAT}{tableForDiscreteLogarithm} &
+\cross{COMPCAT}{tan} &
+\cross{COMPCAT}{tanh} \\
+\cross{COMPCAT}{trace} &
+\cross{COMPCAT}{traceMatrix} &
+\cross{COMPCAT}{unit?} \\
+\cross{COMPCAT}{unitCanonical} &
+\cross{COMPCAT}{unitNormal} &
+\cross{COMPCAT}{zero?} \\
+\cross{COMPCAT}{?*?} &
+\cross{COMPCAT}{?**?} &
+\cross{COMPCAT}{?+?} \\
+\cross{COMPCAT}{?-?} &
+\cross{COMPCAT}{-?} &
+\cross{COMPCAT}{?=?} \\
+\cross{COMPCAT}{?\^{}?} &
+\cross{COMPCAT}{?\~{}=?} &
+\cross{COMPCAT}{?/?} \\
+\cross{COMPCAT}{?$<$?} &
+\cross{COMPCAT}{?$<=$?} &
+\cross{COMPCAT}{?$>$?} \\
+\cross{COMPCAT}{?$>=$?} &
+\cross{COMPCAT}{?.?} &
+\cross{COMPCAT}{?quo?} \\
+\cross{COMPCAT}{?rem?} &&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item if \#1 has multiplicativeValuation then multiplicativeValuation where
+{\bf \cross{COMPCAT}{multiplicativeValuation}}
+implies\\
+{\tt euclideanSize(a*b)=euclideanSize(a)*euclideanSize(b)}.
+\item if \#1 has additiveValuation then additiveValuation where
+{\bf \cross{COMPCAT}{additiveValuation}}
+implies\\
+{\tt euclideanSize(a*b)=euclideanSize(a)+euclideanSize(b)}.
+\item if \#1 has Field then canonicalsClosed where
+{\bf \cross{COMPCAT}{canonicalsClosed}}
+is true if\\
+{\tt unitCanonical(a)*unitCanonical(b) = unitCanonical(a*b)}.
+\item if \#1 has Field then canonicalUnitNormal where
+{\bf \cross{COMPCAT}{canonicalUnitNormal}}
+is true if we can choose a canonical representative for each class 
+of associate elements, that is {\tt associates?(a,b)} returns true 
+if and only if {\tt unitCanonical(a) = unitCanonical(b)}.
+\item if \#1 has IntegralDomain or \#1 has both EuclideanDomain and 
+PolynomialFactorizationExplicit then noZeroDivisors where
+{\bf \cross{COMPCAT}{noZeroDivisors}}
+is true if $x * y \ne 0$ implies both x and y are non-zero.
+\item {\bf \cross{COMPCAT}{commutative(``*'')}}
+is true if it has an operation $"*": (D,D) -> D$
+which is commutative.
+\item {\bf \cross{COMPCAT}{unitsKnown}}
+is true if a monoid (a multiplicative semigroup with a 1) has 
+unitsKnown means that  the operation {\tt recip} can only return 
+``failed'' if its argument is not a unit.
+\item {\bf \cross{COMPCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{COMPCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item {\bf \cross{COMPCAT}{complex}} means that this domain has $\sqrt{-1}$
+\item {\bf nil}
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ abs : % -> % if R has RNS            
+ argument : % -> R if R has TRANFUN
+ complex : (R,R) -> %
+ conjugate : % -> %                   
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ imag : % -> R                        
+ imaginary : () -> %
+ norm : % -> R
+ polarCoordinates : % -> Record(r: R,phi: R) if R has RNS and R has TRANFUN
+ rational : % -> Fraction Integer if R has INS
+ rational? : % -> Boolean if R has INS
+ rationalIfCan : % -> Union(Fraction Integer,"failed") if R has INS
+ real : % -> R
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ acos : % -> % if R has TRANFUN
+ acosh : % -> % if R has TRANFUN
+ asin : % -> % if R has TRANFUN
+ asinh : % -> % if R has TRANFUN
+ atan : % -> % if R has TRANFUN
+ atanh : % -> % if R has TRANFUN
+ characteristic : () -> NonNegativeInteger
+ characteristicPolynomial : % -> SparseUnivariatePolynomial R
+ coerce : % -> OutputForm             
+ convert : % -> Complex DoubleFloat if R has REAL
+ convert : % -> Complex Float if R has REAL
+ convert : % -> InputForm if R has KONVERT INFORM
+ convert : % -> Pattern Float if R has KONVERT PATTERN FLOAT
+ convert : % -> Pattern Integer if R has KONVERT PATTERN INT
+ coordinates : % -> Vector R
+ coordinates : (%,Vector %) -> Vector R
+ cos : % -> % if R has TRANFUN
+ cosh : % -> % if R has TRANFUN
+ definingPolynomial : () -> SparseUnivariatePolynomial R
+ differentiate : (%,(R -> R)) -> %
+ discriminant : () -> R               
+ divide : (%,%) -> Record(quotient: %,remainder: %) if R has EUCDOM
+ euclideanSize : % -> NonNegativeInteger if R has EUCDOM
+ exp : % -> % if R has TRANFUN
+ exquo : (%,%) -> Union(%,"failed") if R has INTDOM or R has EUCDOM and R has PFECAT
+ factorPolynomial : SparseUnivariatePolynomial % -> Factored SparseUnivariatePolynomial % if R has EUCDOM and R has PFECAT
+ factorSquareFreePolynomial : SparseUnivariatePolynomial % -> Factored SparseUnivariatePolynomial % if R has EUCDOM and R has PFECAT
+ inv : % -> % if R has FIELD          
+ lift : % -> SparseUnivariatePolynomial R
+ log : % -> % if R has TRANFUN
+ map : ((R -> R),%) -> %              
+ minimalPolynomial : % -> SparseUnivariatePolynomial R if R has FIELD
+ patternMatch : (%,Pattern Integer,PatternMatchResult(Integer,%)) -> PatternMatchResult(Integer,%) if R has PATMAB INT
+ patternMatch : (%,Pattern Float,PatternMatchResult(Float,%)) -> PatternMatchResult(Float,%) if R has PATMAB FLOAT
+ pi : () -> % if R has TRANFUN
+ rank : () -> PositiveInteger         
+ recip : % -> Union(%,"failed")       
+ reduce : SparseUnivariatePolynomial R -> %
+ reducedSystem : Matrix % -> Matrix R
+ reducedSystem : Matrix % -> Matrix Integer if R has LINEXP INT
+ retract : % -> R                     
+ retractIfCan : % -> Union(R,"failed")
+ sin : % -> % if R has TRANFUN
+ sinh : % -> % if R has TRANFUN
+ solveLinearPolynomialEquation : (List SparseUnivariatePolynomial %,SparseUnivariatePolynomial %) -> Union(List SparseUnivariatePolynomial %,"failed") if R has EUCDOM and R has PFECAT
+ tan : % -> % if R has TRANFUN
+ tanh : % -> % if R has TRANFUN
+ trace : % -> R                       
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %) if R has INTDOM or R has EUCDOM and R has PFECAT
+ ?=? : (%,%) -> Boolean
+ ?+? : (%,%) -> %                     
+ -? : % -> %                          
+ ?*? : (%,%) -> %                     
+ ?*? : (R,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?<? : (%,%) -> Boolean if R has ORDSET
+ ?**? : (%,Fraction Integer) -> % if R has RADCAT and R has TRANFUN
+ ?rem? : (%,%) -> % if R has EUCDOM
+ ?quo? : (%,%) -> % if R has EUCDOM
+\end{verbatim}
+
+These exports come from \refto{MonogenicAlgebra}(R,S)\\
+where R:CommutativeRing and S:SparseUnivariatePolynomial(R):
+\begin{verbatim}
+ 0 : () -> %                          
+ 1 : () -> %
+ associates? : (%,%) -> Boolean if R has INTDOM or R has EUCDOM and R has PFECAT
+ basis : () -> Vector %
+ charthRoot : % -> Union(%,"failed") if and(has($,CharacteristicNonZero),AND(has(R,EuclideanDomain),has(R,PolynomialFactorizationExplicit))) or R has CHARNZ
+ charthRoot : % -> % if R has FFIELDC
+ coerce : R -> %                      
+ coerce : % -> % if R has INTDOM or R has EUCDOM and R has PFECAT
+ coerce : Integer -> %
+ coerce : Fraction Integer -> % if R has FIELD or R has RETRACT FRAC INT
+ conditionP : Matrix % -> Union(Vector %,"failed") if and(has($,CharacteristicNonZero),AND(has(R,EuclideanDomain),has(R,PolynomialFactorizationExplicit))) or R has FFIELDC
+ convert : SparseUnivariatePolynomial R -> %
+ convert : Vector R -> %
+ convert : % -> Vector R              
+ convert : % -> SparseUnivariatePolynomial R
+ coordinates : Vector % -> Matrix R
+ coordinates : (Vector %,Vector %) -> Matrix R
+ createPrimitiveElement : () -> % if R has FFIELDC
+ D : (%,(R -> R)) -> %                
+ D : (%,(R -> R),NonNegativeInteger) -> %
+ D : % -> % if and(has(R,Field),has(R,DifferentialRing)) or R has DIFRING or and(has(R,DifferentialRing),has(R,Field))
+ D : (%,NonNegativeInteger) -> % if and(has(R,Field),has(R,DifferentialRing)) or R has DIFRING or and(has(R,DifferentialRing),has(R,Field))
+ D : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
+ D : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ D : (%,List Symbol) -> % if R has PDRING SYMBOL
+ D : (%,Symbol) -> % if R has PDRING SYMBOL
+ derivationCoordinates : (Vector %,(R -> R)) -> Matrix R if R has FIELD
+ differentiate : (%,NonNegativeInteger) -> % if and(has(R,Field),has(R,DifferentialRing)) or R has DIFRING or and(has(R,DifferentialRing),has(R,Field))
+ differentiate : (%,List Symbol) -> % if R has PDRING SYMBOL
+ differentiate : (%,Symbol,NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> % if R has PDRING SYMBOL
+ differentiate : (%,(R -> R),NonNegativeInteger) -> %
+ differentiate : % -> % if and(has(R,Field),has(R,DifferentialRing)) or R has DIFRING or and(has(R,DifferentialRing),has(R,Field))
+ differentiate : (%,Symbol) -> % if R has PDRING SYMBOL
+ discreteLog : (%,%) -> Union(NonNegativeInteger,"failed") if R has FFIELDC
+ discreteLog : % -> NonNegativeInteger if R has FFIELDC
+ discriminant : Vector % -> R
+ expressIdealMember : (List %,%) -> Union(List %,"failed") if R has EUCDOM
+ extendedEuclidean : (%,%) -> Record(coef1: %,coef2: %,generator: %) if R has EUCDOM
+ extendedEuclidean : (%,%,%) -> Union(Record(coef1: %,coef2: %),"failed") if R has EUCDOM
+ factor : % -> Factored % if R has EUCDOM and R has PFECAT or R has FIELD
+ factorsOfCyclicGroupSize : () -> List Record(factor: Integer,exponent: Integer) if R has FFIELDC
+ gcd : (%,%) -> % if R has EUCDOM or R has EUCDOM and R has PFECAT
+ gcd : List % -> % if R has EUCDOM or R has EUCDOM and R has PFECAT
+ gcdPolynomial : (SparseUnivariatePolynomial %,SparseUnivariatePolynomial %) -> SparseUnivariatePolynomial % if R has EUCDOM or R has EUCDOM and R has PFECAT
+ generator : () -> %                  
+ hash : % -> SingleInteger
+ index : PositiveInteger -> % if R has FINITE
+ init : () -> % if R has FFIELDC
+ latex : % -> String
+ lcm : (%,%) -> % if R has EUCDOM or R has EUCDOM and R has PFECAT
+ lcm : List % -> % if R has EUCDOM or R has EUCDOM and R has PFECAT
+ lookup : % -> PositiveInteger if R has FINITE
+ multiEuclidean : (List %,%) -> Union(List %,"failed") if R has EUCDOM
+ nextItem : % -> Union(%,"failed") if R has FFIELDC
+ one? : % -> Boolean                  
+ order : % -> OnePointCompletion PositiveInteger if R has FFIELDC
+ order : % -> PositiveInteger if R has FFIELDC
+ prime? : % -> Boolean if R has EUCDOM and R has PFECAT or R has FIELD
+ primeFrobenius : % -> % if R has FFIELDC
+ primeFrobenius : (%,NonNegativeInteger) -> % if R has FFIELDC
+ primitive? : % -> Boolean if R has FFIELDC
+ primitiveElement : () -> % if R has FFIELDC
+ principalIdeal : List % -> Record(coef: List %,generator: %) if R has EUCDOM
+ random : () -> % if R has FINITE
+ reduce : Fraction SparseUnivariatePolynomial R -> Union(%,"failed") if R has FIELD
+ reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix R,vec: Vector R)
+ reducedSystem : (Matrix %,Vector %) -> Record(mat: Matrix Integer,vec: Vector Integer) if R has LINEXP INT
+ regularRepresentation : % -> Matrix R
+ regularRepresentation : (%,Vector %) -> Matrix R
+ representationType : () -> Union("prime",polynomial,normal,cyclic) if R has FFIELDC
+ represents : (Vector R,Vector %) -> %
+ represents : Vector R -> %
+ retract : % -> Fraction Integer if R has RETRACT FRAC INT
+ retract : % -> Integer if R has RETRACT INT
+ retractIfCan : % -> Union(Fraction Integer,"failed") if R has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed") if R has RETRACT INT
+ sample : () -> %
+ size : () -> NonNegativeInteger if R has FINITE
+ sizeLess? : (%,%) -> Boolean if R has EUCDOM
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ squareFree : % -> Factored % if R has EUCDOM and R has PFECAT or R has FIELD
+ squareFreePart : % -> % if R has EUCDOM and R has PFECAT or R has FIELD
+ tableForDiscreteLogarithm : Integer -> Table(PositiveInteger,NonNegativeInteger) if R has FFIELDC
+ traceMatrix : () -> Matrix R
+ traceMatrix : Vector % -> Matrix R
+ unit? : % -> Boolean if R has INTDOM or R has EUCDOM and R has PFECAT
+ unitCanonical : % -> % if R has INTDOM or R has EUCDOM and R has PFECAT
+ zero? : % -> Boolean                 
+ ?/? : (%,%) -> % if R has FIELD
+ ?*? : (%,Fraction Integer) -> % if R has FIELD
+ ?*? : (Fraction Integer,%) -> % if R has FIELD
+ ?**? : (%,Integer) -> % if R has FIELD
+ ?^? : (%,Integer) -> % if R has FIELD
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (%,R) -> %
+ ?-? : (%,%) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+ ?^? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from \refto{FullyEvalableOver}(R:CommutativeRing)
+\begin{verbatim}
+ ?.? : (%,R) -> % if R has ELTAB(R,R)
+ eval : (%,Equation R) -> % if R has EVALAB R
+ eval : (%,List Symbol,List R) -> % if R has IEVALAB(SYMBOL,R)
+ eval : (%,List Equation R) -> % if R has EVALAB R
+ eval : (%,R,R) -> % if R has EVALAB R
+ eval : (%,List R,List R) -> % if R has EVALAB R
+ eval : (%,Symbol,R) -> % if R has IEVALAB(SYMBOL,R)
+\end{verbatim}
+
+These exports come from \refto{CommutativeRing}():
+\begin{verbatim}
+ ?~=? : (%,%) -> Boolean
+\end{verbatim}
+
+These exports come from \refto{OrderedSet}():
+\begin{verbatim}
+ max : (%,%) -> % if R has ORDSET
+ min : (%,%) -> % if R has ORDSET
+ ?<=? : (%,%) -> Boolean if R has ORDSET
+ ?>? : (%,%) -> Boolean if R has ORDSET
+ ?>=? : (%,%) -> Boolean if R has ORDSET
+\end{verbatim}
+
+These exports come from \refto{RadicalCategory}():
+\begin{verbatim}
+ nthRoot : (%,Integer) -> % if R has RADCAT and R has TRANFUN
+ sqrt : % -> % if R has RADCAT and R has TRANFUN
+\end{verbatim}
+
+These exports come from \refto{TranscendentalFunctionCategory}():
+\begin{verbatim}
+ acot : % -> % if R has TRANFUN
+ acoth : % -> % if R has TRANFUN
+ acsc : % -> % if R has TRANFUN
+ acsch : % -> % if R has TRANFUN
+ asec : % -> % if R has TRANFUN
+ asech : % -> % if R has TRANFUN
+ cot : % -> % if R has TRANFUN
+ coth : % -> % if R has TRANFUN
+ csc : % -> % if R has TRANFUN
+ csch : % -> % if R has TRANFUN
+ sec : % -> % if R has TRANFUN
+ sech : % -> % if R has TRANFUN
+ ?**? : (%,%) -> % if R has TRANFUN
+\end{verbatim}
+
+These exports come from \refto{PolynomialFactorizationExplicit}():
+\begin{verbatim}
+ squareFreePolynomial : SparseUnivariatePolynomial % -> Factored SparseUnivariatePolynomial % if R has EUCDOM and R has PFECAT
+\end{verbatim}
+
+<<category COMPCAT ComplexCategory>>=
+)abbrev category COMPCAT ComplexCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated: 18 March 1994
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex, gaussian
+++ References:
+++ Description:
+++ This category represents the extension of a ring by a square
+++ root of -1.
+ComplexCategory(R:CommutativeRing): Category ==
+  Join(MonogenicAlgebra(R, SparseUnivariatePolynomial R), FullyRetractableTo R,
+   DifferentialExtension R, FullyEvalableOver R, FullyPatternMatchable(R),
+    Patternable(R), FullyLinearlyExplicitRingOver R, CommutativeRing) with
+     complex                       ++ indicates that % has sqrt(-1)
+     imaginary:   () -> %          ++ imaginary() = sqrt(-1) = %i.
+     conjugate:   % -> %           ++ conjugate(x + %i y) returns x - %i y.
+     complex  :   (R, R) -> %      ++ complex(x,y) constructs x + %i*y.
+     imag     :   % -> R           ++ imag(x) returns imaginary part of x.
+     real     :   % -> R           ++ real(x) returns real part of x.
+     norm     :   % -> R           ++ norm(x) returns x * conjugate(x)
+     if R has OrderedSet then OrderedSet
+     if R has IntegralDomain then
+       IntegralDomain
+       _exquo : (%,R) -> Union(%,"failed")
+         ++ exquo(x, r) returns the exact quotient of x by r, or
+         ++ "failed" if r does not divide x exactly.
+     if R has EuclideanDomain then EuclideanDomain
+     if R has multiplicativeValuation then multiplicativeValuation
+     if R has additiveValuation then additiveValuation
+     if R has Field then        -- this is a lie; we must know that
+       Field                    -- x**2+1 is irreducible in R
+     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+     if R has CharacteristicZero then CharacteristicZero
+     if R has CharacteristicNonZero then CharacteristicNonZero
+     if R has RealConstant then
+       ConvertibleTo Complex DoubleFloat
+       ConvertibleTo Complex Float
+     if R has RealNumberSystem then
+       abs: % -> %
+         ++ abs(x) returns the absolute value of x = sqrt(norm(x)).
+     if R has TranscendentalFunctionCategory then
+       TranscendentalFunctionCategory
+       argument: % -> R  
+         ++ argument(x) returns the angle made by (0,1) and (0,x).
+       if R has RadicalCategory then RadicalCategory
+       if R has RealNumberSystem then
+         polarCoordinates: % -> Record(r:R, phi:R)
+           ++ polarCoordinates(x) returns (r, phi) such that 
+           ++ x = r * exp(%i * phi).
+     if R has IntegerNumberSystem then
+       rational?    : % -> Boolean
+         ++ rational?(x) tests if x is a rational number.
+       rational     : % -> Fraction Integer
+         ++ rational(x) returns x as a rational number.
+         ++ Error: if x is not a rational number.
+       rationalIfCan: % -> Union(Fraction Integer, "failed")
+         ++ rationalIfCan(x) returns x as a rational number, or
+         ++ "failed" if x is not a rational number.
+     if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
+        PolynomialFactorizationExplicit
+ add
+       import MatrixCategoryFunctions2(%, Vector %, Vector %, Matrix %,
+                                       R, Vector R, Vector R, Matrix R)
+       SUP ==> SparseUnivariatePolynomial
+       characteristicPolynomial x ==
+          v := monomial(1,1)$SUP(R)
+          v**2 - trace(x)*v**1 + norm(x)*v**0
+       if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
+          SupR ==> SparseUnivariatePolynomial R
+          Sup ==> SparseUnivariatePolynomial %
+          import FactoredFunctionUtilities Sup
+          import UnivariatePolynomialCategoryFunctions2(R,SupR,%,Sup)
+          import UnivariatePolynomialCategoryFunctions2(%,Sup,R,SupR)
+          pp,qq:Sup
+          if R has IntegerNumberSystem then
+             myNextPrime: (%,NonNegativeInteger) -> %
+             myNextPrime(x,n ) == -- prime is actually in R, and = 3(mod 4)
+                xr:=real(x)-4::R
+                while not prime? xr repeat
+                   xr:=xr-4::R
+                complex(xr,0)
+             --!TT:=InnerModularGcd(%,Sup,32719 :: %,myNextPrime)
+             --!gcdPolynomial(pp,qq) == modularGcd(pp,qq)$TT
+             solveLinearPolynomialEquation(lp:List Sup,p:Sup) ==
+               solveLinearPolynomialEquation(lp,p)$ComplexIntegerSolveLinearPolynomialEquation(R,%)
+          normPolynomial: Sup -> SupR
+          normPolynomial pp ==
+              map(retract(#1@%)::R,pp * map(conjugate,pp))
+          factorPolynomial pp ==
+              refine(squareFree pp,factorSquareFreePolynomial)
+          factorSquareFreePolynomial pp ==
+              pnorm:=normPolynomial pp
+              k:R:=0
+              while degree gcd(pnorm,differentiate pnorm)>0 repeat
+                 k:=k+1
+                 pnorm:=normPolynomial
+                          elt(pp,monomial(1,1)-monomial(complex(0,k),0))
+              fR:=factorSquareFreePolynomial pnorm
+              numberOfFactors fR = 1 =>
+                  makeFR(1,[["irred",pp,1]])
+              lF:List Record(flg:Union("nil", "sqfr", "irred", "prime"),
+                             fctr:Sup, xpnt:Integer):=[]
+              for u in factorList fR repeat
+                  p1:=map((#1@R)::%,u.fctr)
+                  if not zero? k then
+                     p1:=elt(p1,monomial(1,1)+monomial(complex(0,k),0))
+                  p2:=gcd(p1,pp)
+                  lF:=cons(["irred",p2,1],lF)
+                  pp:=(pp exquo p2)::Sup
+              makeFR(pp,lF)
+       rank()           == 2
+       discriminant()   == -4 :: R
+       norm x           == real(x)**2 + imag(x)**2
+       trace x          == 2 * real x
+       imaginary()      == complex(0, 1)
+       conjugate x      == complex(real x, - imag x)
+       characteristic() == characteristic()$R
+       map(fn, x)       == complex(fn real x, fn imag x)
+       x = y            == real(x) = real(y) and imag(x) = imag(y)
+       x + y            == complex(real x + real y, imag x + imag y)
+       - x              == complex(- real x, - imag x)
+       r:R * x:%        == complex(r * real x, r * imag x)
+       coordinates(x:%) == [real x, imag x]
+       n:Integer * x:%  == complex(n * real x, n * imag x)
+       differentiate(x:%, d:R -> R) == complex(d real x, d imag x)
+
+       definingPolynomial() ==
+         monomial(1,2)$(SUP R) + monomial(1,0)$(SUP R)
+
+       reduce(pol:SUP R) ==
+         part:= (monicDivide(pol,definingPolynomial())).remainder
+         complex(coefficient(part,0),coefficient(part,1))
+
+       lift(x) == monomial(real x,0)$(SUP R)+monomial(imag x,1)$(SUP R)
+
+       minimalPolynomial x ==
+         zero? imag x =>
+           monomial(1, 1)$(SUP R) - monomial(real x, 0)$(SUP R)
+         monomial(1, 2)$(SUP R) - monomial(trace x, 1)$(SUP R)
+           + monomial(norm x, 0)$(SUP R)
+
+       coordinates(x:%, v:Vector %):Vector(R) ==
+         ra := real(a := v(minIndex v))
+         rb := real(b := v(maxIndex v))
+         (#v ^= 2) or
+           ((d := recip(ra * (ib := imag b) - (ia := imag a) * rb))
+             case "failed") =>error "coordinates: vector is not a basis"
+         rx := real x
+         ix := imag x
+         [d::R * (rx * ib - ix * rb), d::R * (ra * ix - ia * rx)]
+
+       coerce(x:%):OutputForm ==
+         re := (r := real x)::OutputForm
+         ie := (i := imag x)::OutputForm
+         zero? i => re
+         outi := "%i"::Symbol::OutputForm
+         ip :=
+--           one? i => outi
+           (i = 1) => outi
+--           one?(-i) => -outi
+           ((-i) = 1) => -outi
+           ie * outi
+         zero? r => ip
+         re + ip
+
+       retract(x:%):R ==
+         not zero?(imag x) =>
+           error "Imaginary part is nonzero. Cannot retract."
+         real x
+
+       retractIfCan(x:%):Union(R, "failed") ==
+         not zero?(imag x) => "failed"
+         real x
+
+       x:% * y:% ==
+         complex(real x * real y - imag x * imag y,
+                  imag x * real y + imag y * real x)
+
+       reducedSystem(m:Matrix %):Matrix R ==
+         vertConcat(map(real, m), map(imag, m))
+
+       reducedSystem(m:Matrix %, v:Vector %):
+        Record(mat:Matrix R, vec:Vector R) ==
+         rh := reducedSystem(v::Matrix %)@Matrix(R)
+         [reducedSystem(m)@Matrix(R), column(rh, minColIndex rh)]
+
+       if R has RealNumberSystem then
+         abs(x:%):%        == (sqrt norm x)::%
+
+       if R has RealConstant then
+         convert(x:%):Complex(DoubleFloat) ==
+          complex(convert(real x)@DoubleFloat,convert(imag x)@DoubleFloat)
+
+         convert(x:%):Complex(Float) ==
+           complex(convert(real x)@Float, convert(imag x)@Float)
+
+       if R has ConvertibleTo InputForm then
+         convert(x:%):InputForm ==
+           convert([convert("complex"::Symbol), convert real x,
+                    convert imag x]$List(InputForm))@InputForm
+
+       if R has ConvertibleTo Pattern Integer then
+         convert(x:%):Pattern Integer ==
+            convert(x)$ComplexPattern(Integer, R, %)
+       if R has ConvertibleTo Pattern Float then
+         convert(x:%):Pattern Float ==
+            convert(x)$ComplexPattern(Float, R, %)
+
+       if R has PatternMatchable Integer then
+         patternMatch(x:%, p:Pattern Integer,
+          l:PatternMatchResult(Integer, %)) ==
+           patternMatch(x, p, l)$ComplexPatternMatch(Integer, R, %)
+
+       if R has PatternMatchable Float then
+         patternMatch(x:%, p:Pattern Float,
+          l:PatternMatchResult(Float, %)) ==
+           patternMatch(x, p, l)$ComplexPatternMatch(Float, R, %)
+
+
+       if R has OrderedSet then
+         x < y ==
+           real x = real y => imag x < imag y
+           real x < real y
+
+       if R has IntegerNumberSystem then
+         rational? x == zero? imag x
+
+         rational x ==
+           zero? imag x => rational real x
+           error "Not a rational number"
+
+         rationalIfCan x ==
+           zero? imag x => rational real x
+           "failed"
+
+       if R has Field then
+         inv x ==
+           zero? imag x => (inv real x)::%
+           r := norm x
+           complex(real(x) / r, - imag(x) / r)
+
+       if R has IntegralDomain then
+         _exquo(x:%, r:R) ==
+--           one? r => x
+           (r = 1) => x
+           (r1 := real(x) exquo r) case "failed" => "failed"
+           (r2 := imag(x) exquo r) case "failed" => "failed"
+           complex(r1, r2)
+
+         _exquo(x:%, y:%) ==
+           zero? imag y => x exquo real y
+           x * conjugate(y) exquo norm(y)
+
+         recip(x:%) == 1 exquo x
+
+         if R has OrderedRing then
+           unitNormal x ==
+             zero? x => [1,x,1]
+             (u := recip x) case % => [x, 1, u]
+             zero? real x =>
+               c := unitNormal imag x
+               [complex(0, c.unit), (c.associate * imag x)::%,
+                                              complex(0, - c.associate)]
+             c := unitNormal real x
+             x := c.associate * x
+             imag x < 0 =>
+               x := complex(- imag x, real x)
+               [- c.unit * imaginary(), x, c.associate * imaginary()]
+             [c.unit ::%, x, c.associate ::%]
+         else
+           unitNormal x ==
+             zero? x => [1,x,1]
+             (u := recip x) case % => [x, 1, u]
+             zero? real x =>
+               c := unitNormal imag x
+               [complex(0, c.unit), (c.associate * imag x)::%,
+                                              complex(0, - c.associate)]
+             c := unitNormal real x
+             x := c.associate * x
+             [c.unit ::%, x, c.associate ::%]
+
+       if R has EuclideanDomain then
+          if R has additiveValuation then
+              euclideanSize x == max(euclideanSize real x,
+                                     euclideanSize imag x)
+          else
+              euclideanSize x == euclideanSize(real(x)**2 + imag(x)**2)$R
+          if R has IntegerNumberSystem then
+            x rem y ==
+              zero? imag y =>
+                yr:=real y
+                complex(symmetricRemainder(real(x), yr),
+                        symmetricRemainder(imag(x), yr))
+              divide(x, y).remainder
+            x quo y ==
+              zero? imag y =>
+                yr:= real y
+                xr:= real x
+                xi:= imag x
+                complex((xr-symmetricRemainder(xr,yr)) quo yr,
+                        (xi-symmetricRemainder(xi,yr)) quo yr)
+              divide(x, y).quotient
+
+          else
+            x rem y ==
+              zero? imag y =>
+                yr:=real y
+                complex(real(x) rem yr,imag(x) rem yr)
+              divide(x, y).remainder
+            x quo y ==
+              zero? imag y => complex(real x quo real y,imag x quo real y)
+              divide(x, y).quotient
+
+          divide(x, y) ==
+            r := norm y
+            y1 := conjugate y
+            xx := x * y1
+            x1 := real(xx) rem r
+            a  := x1
+            if x1^=0 and sizeLess?(r, 2 * x1) then
+              a := x1 - r
+              if sizeLess?(x1, a) then a := x1 + r
+            x2 := imag(xx) rem r
+            b  := x2
+            if x2^=0 and sizeLess?(r, 2 * x2) then
+              b := x2 - r
+              if sizeLess?(x2, b) then b := x2 + r
+            y1 := (complex(a, b) exquo y1)::%
+            [((x - y1) exquo y)::%, y1]
+
+       if R has TranscendentalFunctionCategory then
+         half := recip(2::R)::R
+
+         if R has RealNumberSystem then
+           atan2loc(y: R, x: R): R ==
+               pi1 := pi()$R
+               pi2 := pi1 * half
+               x = 0 => if y >= 0 then pi2 else -pi2
+
+               -- Atan in (-pi/2,pi/2]
+               theta := atan(y * recip(x)::R)
+               while theta <= -pi2 repeat theta := theta + pi1
+               while theta >   pi2 repeat theta := theta - pi1
+
+               x >= 0 => theta      -- I or IV
+
+               if y >= 0 then
+                   theta + pi1      -- II
+               else
+                   theta - pi1      -- III
+
+           argument x == atan2loc(imag x, real x)
+
+         else
+           -- Not ordered so dictate two quadrants
+           argument x ==
+             zero? real x => pi()$R * half
+             atan(imag(x) * recip(real x)::R)
+
+         pi()  == pi()$R :: %
+
+         if R is DoubleFloat then
+            stoc ==> S_-TO_-C$Lisp
+            ctos ==> C_-TO_-S$Lisp
+
+            exp   x == ctos EXP(stoc x)$Lisp
+            log   x == ctos LOG(stoc x)$Lisp
+
+            sin   x == ctos SIN(stoc x)$Lisp
+            cos   x == ctos COS(stoc x)$Lisp
+            tan   x == ctos TAN(stoc x)$Lisp
+            asin  x == ctos ASIN(stoc x)$Lisp
+            acos  x == ctos ACOS(stoc x)$Lisp
+            atan  x == ctos ATAN(stoc x)$Lisp
+
+            sinh  x == ctos SINH(stoc x)$Lisp
+            cosh  x == ctos COSH(stoc x)$Lisp
+            tanh  x == ctos TANH(stoc x)$Lisp
+            asinh x == ctos ASINH(stoc x)$Lisp
+            acosh x == ctos ACOSH(stoc x)$Lisp
+            atanh x == ctos ATANH(stoc x)$Lisp
+
+         else
+           atan x ==
+             ix := imaginary()*x
+             - imaginary() * half * (log(1 + ix) - log(1 - ix))
+
+           log x ==
+             complex(log(norm x) * half, argument x)
+
+           exp x ==
+             e := exp real x
+             complex(e * cos imag x, e * sin imag x)
+
+           cos x ==
+             e := exp(imaginary() * x)
+             half * (e + recip(e)::%)
+
+           sin x ==
+             e := exp(imaginary() * x)
+             - imaginary() * half * (e - recip(e)::%)
+
+         if R has RealNumberSystem then
+           polarCoordinates x ==
+             [sqrt norm x, (negative?(t := argument x) => t + 2 * pi(); t)]
+
+           x:% ** q:Fraction(Integer) ==
+             zero? q =>
+               zero? x => error "0 ** 0 is undefined"
+               1
+             zero? x => 0
+             rx := real x
+             zero? imag x and positive? rx => (rx ** q)::%
+             zero? imag x and denom q = 2 => complex(0, (-rx)**q)
+             ax := sqrt(norm x) ** q
+             tx := q::R * argument x
+             complex(ax * cos tx, ax * sin tx)
+
+         else if R has RadicalCategory then
+           x:% ** q:Fraction(Integer) ==
+             zero? q =>
+               zero? x => error "0 ** 0 is undefined"
+               1
+             r := real x
+             zero?(i := imag x) => (r ** q)::%
+             t := numer(q) * recip(denom(q)::R)::R * argument x
+             e:R :=
+               zero? r => i ** q
+               norm(x) ** (q / (2::Fraction(Integer)))
+             complex(e * cos t, e * sin t)
+
+@
+<<COMPCAT.dotabb>>=
+"COMPCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=COMPCAT"];
+"COMPCAT" -> "COMRING"
+"COMPCAT" -> "DIFEXT"
+"COMPCAT" -> "FEVALAB"
+"COMPCAT" -> "FPATMAB"
+"COMPCAT" -> "FRETRCT"
+"COMPCAT" -> "MONOGEN"
+"COMPCAT" -> "PATAB"
+"COMPCAT" -> "FLINEXP"
+"COMPCAT" -> "ORDSET"
+
+@
+<<COMPCAT.dotfull>>=
+"ComplexCategory(R:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=COMPCAT"];
+"ComplexCategory(R:CommutativeRing)" -> 
+  "MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "FullyRetractableTo(a:CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "DifferentialExtension(CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "FullyEvalableOver(CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "FullyPatternMatchable(CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "Patternable(CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "FullyLinearlyExplicitRingOver(a:CommutativeRing)"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "CommutativeRing()"
+"ComplexCategory(R:CommutativeRing)" -> 
+  "OrderedSet()"
+
+@
+<<COMPCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"ComplexCategory(R:CommutativeRing)" [color=lightblue];
+"ComplexCategory(R:CommutativeRing)" -> "MONOGEN..."
+"ComplexCategory(R:CommutativeRing)" -> "FRETRCT..."
+"ComplexCategory(R:CommutativeRing)" -> "DIFEXT..."
+"ComplexCategory(R:CommutativeRing)" -> "FEVALAB..."
+"ComplexCategory(R:CommutativeRing)" -> "FPATMAB..."
+"ComplexCategory(R:CommutativeRing)" -> "PATAB..."
+"ComplexCategory(R:CommutativeRing)" -> "FLINEXP..."
+"ComplexCategory(R:CommutativeRing)" -> "COMRING..."
+"ComplexCategory(R:CommutativeRing)" -> "ORDSET..."
+
+"MONOGEN..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+"DIFEXT..." [color=lightblue];
+"FEVALAB..." [color=lightblue];
+"COMRING..." [color=lightblue];
+"FPATMAB..." [color=lightblue];
+"PATAB..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+"ORDSET..." [color=lightblue];
+}
+
+@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FunctionFieldCategory}{FFCAT}
 \pagepic{ps/v102functionfieldcategory.ps}{FFCAT}{0.70}
@@ -66548,200 +70437,210 @@ Note that this code is not included in the generated catdef.spad file.
 @
 \chapter{Chunk collections}
 <<algebra>>=
-<<category ABELGRP AbelianGroup>>
-<<category ABELMON AbelianMonoid>>
-<<category ABELSG AbelianSemiGroup>>
-<<category ACF AlgebraicallyClosedField>>
-<<category ACFS AlgebraicallyClosedFunctionSpace>>
-<<category AGG Aggregate>>
 <<category AHYP ArcHyperbolicFunctionCategory>>
-<<category ALAGG AssociationListAggregate>>
-<<category ALGEBRA Algebra>>
-<<category AMR AbelianMonoidRing>>
-<<category ARR2CAT TwoDimensionalArrayCategory>>
 <<category ATRIG ArcTrigonometricFunctionCategory>>
 <<category ATTREG AttributeRegistry>>
-<<category A1AGG OneDimensionalArrayAggregate>>
 <<category BASTYPE BasicType>>
-<<category BGAGG BagAggregate>>
-<<category BMODULE BiModule>>
-<<category BRAGG BinaryRecursiveAggregate>>
-<<category BTAGG BitAggregate>>
-<<category BTCAT BinaryTreeCategory>>
-<<category CABMON CancellationAbelianMonoid>>
-<<category CACHSET CachableSet>>
+<<category KOERCE CoercibleTo>>
 <<category CFCAT CombinatorialFunctionCategory>>
-<<category CHARNZ CharacteristicNonZero>>
-<<category CHARZ CharacteristicZero>>
-<<category CLAGG Collection>>
-<<category COMBOPC CombinatorialOpsCategory>>
-<<category COMRING CommutativeRing>>
-<<category DIAGG Dictionary>>
-<<category DIFEXT DifferentialExtension>>
-<<category DIFRING DifferentialRing>>
-<<category DIOPS DictionaryOperations>>
-<<category DIRPCAT DirectProductCategory>>
-<<category DIVRING DivisionRing>>
-<<category DLAGG DoublyLinkedAggregate>>
-<<category DPOLCAT DifferentialPolynomialCategory>>
-<<category DQAGG DequeueAggregate>>
-<<category DVARCAT DifferentialVariableCategory>>
-<<category ELAGG ExtensibleLinearAggregate>>
+<<category KONVERT ConvertibleTo>>
 <<category ELEMFUN ElementaryFunctionCategory>>
 <<category ELTAB Eltable>>
+<<category HYPCAT HyperbolicFunctionCategory>>
+<<category IEVALAB InnerEvalable>>
+<<category OM OpenMath>>
+<<category PTRANFN PartialTranscendentalFunctions>>
+<<category PATAB Patternable>>
+<<category PRIMCAT PrimitiveFunctionCategory>>
+<<category RADCAT RadicalCategory>>
+<<category RETRACT RetractableTo>>
+<<category SPFCAT SpecialFunctionCategory>>
+<<category TRIGCAT TrigonometricFunctionCategory>>
+<<category TYPE Type>>
+<<category AGG Aggregate>>
+<<category COMBOPC CombinatorialOpsCategory>>
 <<category ELTAGG EltableAggregate>>
-<<category ENTIRER EntireRing>>
-<<category ES ExpressionSpace>>
-<<category EUCDOM EuclideanDomain>>
 <<category EVALAB Evalable>>
-<<category FAMONC FreeAbelianMonoidCategory>>
-<<category FAMR FiniteAbelianMonoidRing>>
-<<category FAXF FiniteAlgebraicExtensionField>>
-<<category FDIVCAT FiniteDivisorCategory>>
-<<category FEVALAB FullyEvalableOver>>
-<<category FFCAT FunctionFieldCategory>>
-<<category FFIELDC FiniteFieldCategory>>
-<<category FIELD Field>>
-<<category FILECAT FileCategory>>
-<<category FINAALG FiniteRankNonAssociativeAlgebra>>
-<<category FINITE Finite>>
-<<category FINRALG FiniteRankAlgebra>>
-<<category FLAGG FiniteLinearAggregate>>
-<<category FLALG FreeLieAlgebra>>
-<<category FLINEXP FullyLinearlyExplicitRingOver>>
-<<category FMCAT FreeModuleCat>>
-<<category FMFUN FortranMatrixFunctionCategory>>
-<<category FMTC FortranMachineTypeCategory>>
-<<category FNCAT FileNameCategory>>
 <<category FORTCAT FortranProgramCategory>>
+<<category FRETRCT FullyRetractableTo>>
+<<category FPATMAB FullyPatternMatchable>>
+<<category LOGIC Logic>>
+<<category PPCURVE PlottablePlaneCurveCategory>>
+<<category PSCURVE PlottableSpaceCurveCategory>>
+<<category REAL RealConstant>>
+<<category SEGCAT SegmentCategory>>
+<<category SETCAT SetCategory>>
+<<category TRANFUN TranscendentalFunctionCategory>>
+<<category ABELSG AbelianSemiGroup>>
 <<category FORTFN FortranFunctionCategory>>
 <<category FMC FortranMatrixCategory>>
-<<category FPATMAB FullyPatternMatchable>>
-<<category FPC FieldOfPrimeCharacteristic>>
-<<category FPS FloatingPointSystem>>
-<<category FRAMALG FramedAlgebra>>
-<<category FRETRCT FullyRetractableTo>>
-<<category FRNAALG FramedNonAssociativeAlgebra>>
-<<category FS FunctionSpace>>
-<<category FSAGG FiniteSetAggregate>>
+<<category FMFUN FortranMatrixFunctionCategory>>
 <<category FVC FortranVectorCategory>>
 <<category FVFUN FortranVectorFunctionCategory>>
-<<category GCDDOM GcdDomain>>
-<<category GRALG GradedAlgebra>>
+<<category FEVALAB FullyEvalableOver>>
+<<category FILECAT FileCategory>>
+<<category FINITE Finite>>
+<<category FNCAT FileNameCategory>>
 <<category GRMOD GradedModule>>
-<<category GROUP Group>>
 <<category HOAGG HomogeneousAggregate>>
-<<category HYPCAT HyperbolicFunctionCategory>>
 <<category IDPC IndexedDirectProductCategory>>
-<<category IEVALAB InnerEvalable>>
-<<category INS IntegerNumberSystem>>
-<<category INTCAT IntervalCategory>>
-<<category INTDOM IntegralDomain>>
-<<category IXAGG IndexedAggregate>>
-<<category KDAGG KeyedDictionary>>
-<<category KOERCE CoercibleTo>>
-<<category KONVERT ConvertibleTo>>
-<<category LALG LeftAlgebra>>
 <<category LFCAT LiouvillianFunctionCategory>>
-<<category LIECAT LieAlgebra>>
-<<category LINEXP LinearlyExplicitRingOver>>
-<<category LMODULE LeftModule>>
-<<category LNAGG LinearAggregate>>
-<<category LOGIC Logic>>
-<<category LSAGG ListAggregate>>
-<<category LZSTAGG LazyStreamAggregate>>
-<<category MATCAT MatrixCategory>>
-<<category MDAGG MultiDictionary>>
-<<category MLO MonogenicLinearOperator>>
-<<category MODULE Module>>
 <<category MONAD Monad>>
+<<category NUMINT NumericalIntegrationCategory>>
+<<category OPTCAT NumericalOptimizationCategory>>
+<<category ODECAT OrdinaryDifferentialEquationsSolverCategory>>
+<<category ORDSET OrderedSet>>
+<<category PDECAT PartialDifferentialEquationsSolverCategory>>
+<<category PATMAB PatternMatchable>>
+<<category RRCC RealRootCharacterizationCategory>>
+<<category SEGXCAT SegmentExpansionCategory>>
+<<category SGROUP SemiGroup>>
+<<category SEXCAT SExpressionCategory>>
+<<category STEP StepThrough>>
+<<category SPACEC ThreeSpaceCategory>>
+<<category ABELMON AbelianMonoid>>
+<<category BGAGG BagAggregate>>
+<<category CACHSET CachableSet>>
+<<category CLAGG Collection>>
+<<category DVARCAT DifferentialVariableCategory>>
+<<category ES ExpressionSpace>>
+<<category GRALG GradedAlgebra>>
+<<category IXAGG IndexedAggregate>>
 <<category MONADWU MonadWithUnit>>
 <<category MONOID Monoid>>
-<<category MONOGEN MonogenicAlgebra>>
+<<category ORDFIN OrderedFinite>>
+<<category RCAGG RecursiveAggregate>>
+<<category ARR2CAT TwoDimensionalArrayCategory>>
+<<category BRAGG BinaryRecursiveAggregate>>
+<<category CABMON CancellationAbelianMonoid>>
+<<category DIOPS DictionaryOperations>>
+<<category DLAGG DoublyLinkedAggregate>>
+<<category GROUP Group>>
+<<category LNAGG LinearAggregate>>
+<<category OASGP OrderedAbelianSemiGroup>>
+<<category ORDMON OrderedMonoid>>
+<<category PSETCAT PolynomialSetCategory>>
+<<category PRQAGG PriorityQueueAggregate>>
+<<category QUAGG QueueAggregate>>
+<<category SETAGG SetAggregate>>
+<<category SKAGG StackAggregate>>
+<<category URAGG UnaryRecursiveAggregate>>
+<<category ABELGRP AbelianGroup>>
+<<category BTCAT BinaryTreeCategory>>
+<<category DIAGG Dictionary>>
+<<category DQAGG DequeueAggregate>>
+<<category ELAGG ExtensibleLinearAggregate>>
+<<category FLAGG FiniteLinearAggregate>>
+<<category FAMONC FreeAbelianMonoidCategory>>
+<<category MDAGG MultiDictionary>>
+<<category OAMON OrderedAbelianMonoid>>
+<<category PERMCAT PermutationCategory>>
+<<category STAGG StreamAggregate>>
+<<category TSETCAT TriangularSetCategory>>
+<<category FDIVCAT FiniteDivisorCategory>>
+<<category FSAGG FiniteSetAggregate>>
+<<category KDAGG KeyedDictionary>>
+<<category LZSTAGG LazyStreamAggregate>>
+<<category LMODULE LeftModule>>
+<<category LSAGG ListAggregate>>
 <<category MSETAGG MultisetAggregate>>
-<<category MTSCAT MultivariateTaylorSeriesCategory>>
-<<category NAALG NonAssociativeAlgebra>>
 <<category NARNG NonAssociativeRng>>
+<<category A1AGG OneDimensionalArrayAggregate>>
+<<category OCAMON OrderedCancellationAbelianMonoid>>
+<<category RSETCAT RegularTriangularSetCategory>>
+<<category RMODULE RightModule>>
+<<category RNG Rng>>
+<<category BMODULE BiModule>>
+<<category BTAGG BitAggregate>>
 <<category NASRING NonAssociativeRing>>
 <<category NTSCAT NormalizedTriangularSetCategory>>
-<<category NUMINT NumericalIntegrationCategory>>
 <<category OAGROUP OrderedAbelianGroup>>
-<<category OAMON OrderedAbelianMonoid>>
 <<category OAMONS OrderedAbelianMonoidSup>>
-<<category OASGP OrderedAbelianSemiGroup>>
-<<category OC OctonionCategory>>
-<<category OCAMON OrderedCancellationAbelianMonoid>>
-<<category ODECAT OrdinaryDifferentialEquationsSolverCategory>>
-<<category OINTDOM OrderedIntegralDomain>>
-<<category OM OpenMath>>
 <<category OMSAGG OrderedMultisetAggregate>>
-<<category OPTCAT NumericalOptimizationCategory>>
-<<category ORDFIN OrderedFinite>>
-<<category ORDMON OrderedMonoid>>
+<<category RING Ring>>
+<<category SFRTCAT SquareFreeRegularTriangularSetCategory>>
+<<category SRAGG StringAggregate>>
+<<category TBAGG TableAggregate>>
+<<category VECTCAT VectorCategory>>
+<<category ALAGG AssociationListAggregate>>
+<<category CHARNZ CharacteristicNonZero>>
+<<category CHARZ CharacteristicZero>>
+<<category COMRING CommutativeRing>>
+<<category DIFRING DifferentialRing>>
+<<category ENTIRER EntireRing>>
+<<category FMCAT FreeModuleCat>>
+<<category LALG LeftAlgebra>>
+<<category LINEXP LinearlyExplicitRingOver>>
+<<category MODULE Module>>
 <<category ORDRING OrderedRing>>
-<<category ORDSET OrderedSet>>
-<<category PADICCT PAdicIntegerCategory>>
-<<category PATAB Patternable>>
-<<category PATMAB PatternMatchable>>
-<<category PDECAT PartialDifferentialEquationsSolverCategory>>
 <<category PDRING PartialDifferentialRing>>
-<<category PERMCAT PermutationCategory>>
-<<category PFECAT PolynomialFactorizationExplicit>>
+<<category PTCAT PointCategory>>
+<<category RMATCAT RectangularMatrixCategory>>
+<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>
+<<category STRICAT StringCategory>>
+<<category OREPCAT UnivariateSkewPolynomialCategory>>
+<<category XALG XAlgebra>>
+<<category ALGEBRA Algebra>>
+<<category DIFEXT DifferentialExtension>>
+<<category FLINEXP FullyLinearlyExplicitRingOver>>
+<<category LIECAT LieAlgebra>>
+<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>
+<<category NAALG NonAssociativeAlgebra>>
+<<category VSPACE VectorSpace>>
+<<category XFALG XFreeAlgebra>>
+<<category DIVRING DivisionRing>>
+<<category FINAALG FiniteRankNonAssociativeAlgebra>>
+<<category FLALG FreeLieAlgebra>>
+<<category INTDOM IntegralDomain>>
+<<category MLO MonogenicLinearOperator>>
+<<category OC OctonionCategory>>
+<<category QUATCAT QuaternionCategory>>
+<<category SMATCAT SquareMatrixCategory>>
+<<category XPOLYC XPolynomialsCat>>
+<<category AMR AbelianMonoidRing>>
+<<category FMTC FortranMachineTypeCategory>>
+<<category FRNAALG FramedNonAssociativeAlgebra>>
+<<category GCDDOM GcdDomain>>
+<<category OINTDOM OrderedIntegralDomain>>
+<<category FAMR FiniteAbelianMonoidRing>>
+<<category INTCAT IntervalCategory>>
+<<category PSCAT PowerSeriesCategory>>
 <<category PID PrincipalIdealDomain>>
+<<category UFD UniqueFactorizationDomain>>
+<<category EUCDOM EuclideanDomain>>
+<<category MTSCAT MultivariateTaylorSeriesCategory>>
+<<category PFECAT PolynomialFactorizationExplicit>>
+<<category UPSCAT UnivariatePowerSeriesCategory>>
+<<category FIELD Field>>
+<<category INS IntegerNumberSystem>>
+<<category PADICCT PAdicIntegerCategory>>
 <<category POLYCAT PolynomialCategory>>
-<<category PPCURVE PlottablePlaneCurveCategory>>
-<<category PSCURVE PlottableSpaceCurveCategory>>
-<<category PRIMCAT PrimitiveFunctionCategory>>
-<<category PRQAGG PriorityQueueAggregate>>
-<<category PSCAT PowerSeriesCategory>>
-<<category PSETCAT PolynomialSetCategory>>
-<<category PTCAT PointCategory>>
+<<category UTSCAT UnivariateTaylorSeriesCategory>>
+<<category ACF AlgebraicallyClosedField>>
+<<category DPOLCAT DifferentialPolynomialCategory>>
+<<category DIRPCAT DirectProductCategory>>
+<<category FPC FieldOfPrimeCharacteristic>>
+<<category FINRALG FiniteRankAlgebra>>
+<<category FS FunctionSpace>>
+<<category MATCAT MatrixCategory>>
 <<category QFCAT QuotientFieldCategory>>
-<<category QUAGG QueueAggregate>>
-<<category RADCAT RadicalCategory>>
-<<category RCAGG RecursiveAggregate>>
-<<category REAL RealConstant>>
-<<category RETRACT RetractableTo>>
-<<category RING Ring>>
-<<category RMATCAT RectangularMatrixCategory>>
-<<category RMODULE RightModule>>
-<<category RNG Rng>>
+<<category RCFIELD RealClosedField>>
 <<category RNS RealNumberSystem>>
 <<category RPOLCAT RecursivePolynomialCategory>>
-<<category RSETCAT RegularTriangularSetCategory>>
-<<category SEGCAT SegmentCategory>>
-<<category SEGXCAT SegmentExpansionCategory>>
-<<category SETAGG SetAggregate>>
-<<category SETCAT SetCategory>>
-<<category SEXCAT SExpressionCategory>>
-<<category SFRTCAT SquareFreeRegularTriangularSetCategory>>
-<<category SGROUP SemiGroup>>
-<<category SKAGG StackAggregate>>
-<<category SMATCAT SquareMatrixCategory>>
-<<category SPACEC ThreeSpaceCategory>>
-<<category SPFCAT SpecialFunctionCategory>>
-<<category SRAGG StringAggregate>>
-<<category STAGG StreamAggregate>>
-<<category STEP StepThrough>>
-<<category TRANFUN TranscendentalFunctionCategory>>
-<<category TRIGCAT TrigonometricFunctionCategory>>
-<<category TSETCAT TriangularSetCategory>>
-<<category TYPE Type>>
-<<category TBAGG TableAggregate>>
-<<category UFD UniqueFactorizationDomain>>
 <<category ULSCAT UnivariateLaurentSeriesCategory>>
-<<category ULSCCAT UnivariateLaurentSeriesConstructorCategory>>
-<<category UPOLYC UnivariatePolynomialCategory>>
-<<category UPSCAT UnivariatePowerSeriesCategory>>
 <<category UPXSCAT UnivariatePuiseuxSeriesCategory>>
-<<category URAGG UnaryRecursiveAggregate>>
-<<category UTSCAT UnivariateTaylorSeriesCategory>>
-<<category VECTCAT VectorCategory>>
-<<category VSPACE VectorSpace>>
-<<category XALG XAlgebra>>
+<<category UPOLYC UnivariatePolynomialCategory>>
+<<category ACFS AlgebraicallyClosedFunctionSpace>>
 <<category XF ExtensionField>>
-<<category XFALG XFreeAlgebra>>
-<<category XPOLYC XPolynomialsCat>>
+<<category FFIELDC FiniteFieldCategory>>
+<<category FPS FloatingPointSystem>>
+<<category FRAMALG FramedAlgebra>>
+<<category ULSCCAT UnivariateLaurentSeriesConstructorCategory>>
+<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>
+<<category FAXF FiniteAlgebraicExtensionField>>
+<<category MONOGEN MonogenicAlgebra>>
+<<category COMPCAT ComplexCategory>>
+<<category FFCAT FunctionFieldCategory>> 
 @
 <<dotabb>>=
 digraph dotabb {
@@ -66750,198 +70649,211 @@ digraph dotabb {
  node [shape=box, color=white, style=filled];
 
 <<CATEGORY.dotabb>>
-<<ABELGRP.dotabb>>
-<<ABELMON.dotabb>>
-<<ABELSG.dotabb>>
-<<ACF.dotabb>>
-<<ACFS.dotabb>>
-<<AGG.dotabb>>
 <<AHYP.dotabb>>
-<<ALAGG.dotabb>>
-<<ALGEBRA.dotabb>>
-<<AMR.dotabb>>
-<<ARR2CAT.dotabb>>
 <<ATRIG.dotabb>>
 <<ATTREG.dotabb>>
-<<A1AGG.dotabb>>
 <<BASTYPE.dotabb>>
-<<BGAGG.dotabb>>
-<<BMODULE.dotabb>>
-<<BRAGG.dotabb>>
-<<BTAGG.dotabb>>
-<<BTCAT.dotabb>>
-<<CABMON.dotabb>>
-<<CACHSET.dotabb>>
+<<KOERCE.dotabb>>
 <<CFCAT.dotabb>>
-<<CHARNZ.dotabb>>
-<<CHARZ.dotabb>>
-<<CLAGG.dotabb>>
-<<COMBOPC.dotabb>>
-<<COMRING.dotabb>>
-<<DIAGG.dotabb>>
-<<DIFEXT.dotabb>>
-<<DIOPS.dotabb>>
-<<DIRPCAT.dotabb>>
-<<DIVRING.dotabb>>
-<<DLAGG.dotabb>>
-<<DPOLCAT.dotabb>>
-<<DQAGG.dotabb>>
-<<DVARCAT.dotabb>>
-<<ELAGG.dotabb>>
+<<KONVERT.dotabb>>
 <<ELEMFUN.dotabb>>
 <<ELTAB.dotabb>>
+<<HYPCAT.dotabb>>
+<<IEVALAB.dotabb>>
+<<OM.dotabb>>
+<<PTRANFN.dotabb>>
+<<PATAB.dotabb>>
+<<PRIMCAT.dotabb>>
+<<RADCAT.dotabb>>
+<<RETRACT.dotabb>>
+<<SPFCAT.dotabb>>
+<<TRIGCAT.dotabb>>
+<<TYPE.dotabb>>
+<<AGG.dotabb>>
+<<COMBOPC.dotabb>>
 <<ELTAGG.dotabb>>
-<<ENTIRER.dotabb>>
-<<ES.dotabb>>
-<<EUCDOM.dotabb>>
 <<EVALAB.dotabb>>
-<<FAMONC.dotabb>>
-<<FAMR.dotabb>>
-<<FAXF.dotabb>>
-<<FDIVCAT.dotabb>>
-<<FEVALAB.dotabb>>
-<<FFCAT.dotabb>>
-<<FFIELDC.dotabb>>
-<<FIELD.dotabb>>
-<<FILECAT.dotabb>>
-<<FINAALG.dotabb>>
-<<FINITE.dotabb>>
-<<FINRALG.dotabb>>
-<<FLAGG.dotabb>>
-<<FLALG.dotabb>>
-<<FLINEXP.dotabb>>
-<<FMCAT.dotabb>>
-<<FMFUN.dotabb>>
-<<FMTC.dotabb>>
-<<FNCAT.dotabb>>
 <<FORTCAT.dotabb>>
+<<FRETRCT.dotabb>>
+<<FPATMAB.dotabb>>
+<<LOGIC.dotabb>>
+<<PPCURVE.dotabb>>
+<<PSCURVE.dotabb>>
+<<REAL.dotabb>>
+<<SEGCAT.dotabb>>
+<<SETCAT.dotabb>>
+<<TRANFUN.dotabb>>
+<<ABELSG.dotabb>>
 <<FORTFN.dotabb>>
 <<FMC.dotabb>>
-<<FPATMAB.dotabb>>
-<<FPC.dotabb>>
-<<FPS.dotabb>>
-<<FRAMALG.dotabb>>
-<<FRETRCT.dotabb>>
-<<FRNAALG.dotabb>>
-<<FS.dotabb>>
-<<FSAGG.dotabb>>
+<<FMFUN.dotabb>>
 <<FVC.dotabb>>
 <<FVFUN.dotabb>>
-<<GCDDOM.dotabb>>
-<<GRALG.dotabb>>
+<<FEVALAB.dotabb>>
+<<FILECAT.dotabb>>
+<<FINITE.dotabb>>
+<<FNCAT.dotabb>>
 <<GRMOD.dotabb>>
 <<HOAGG.dotabb>>
-<<HYPCAT.dotabb>>
 <<IDPC.dotabb>>
-<<IEVALAB.dotabb>>
-<<INS.dotabb>>
-<<INTCAT.dotabb>>
-<<INTDOM.dotabb>>
-<<IXAGG.dotabb>>
-<<KDAGG.dotabb>>
-<<KOERCE.dotabb>>
-<<KONVERT.dotabb>>
-<<LALG.dotabb>>
 <<LFCAT.dotabb>>
-<<LIECAT.dotabb>>
-<<LINEXP.dotabb>>
-<<LMODULE.dotabb>>
-<<LNAGG.dotabb>>
-<<LOGIC.dotabb>>
-<<LSAGG.dotabb>>
-<<LZSTAGG.dotabb>>
-<<MATCAT.dotabb>>
-<<MDAGG.dotabb>>
-<<MLO.dotabb>>
-<<MODULE.dotabb>>
 <<MONAD.dotabb>>
+<<NUMINT.dotabb>>
+<<OPTCAT.dotabb>>
+<<ODECAT.dotabb>>
+<<ORDSET.dotabb>>
+<<PDECAT.dotabb>>
+<<PATMAB.dotabb>>
+<<RRCC.dotabb>>
+<<SEGXCAT.dotabb>>
+<<SGROUP.dotabb>>
+<<SEXCAT.dotabb>>
+<<STEP.dotabb>>
+<<SPACEC.dotabb>>
+<<ABELMON.dotabb>>
+<<BGAGG.dotabb>>
+<<CACHSET.dotabb>>
+<<CLAGG.dotabb>>
+<<DVARCAT.dotabb>>
+<<ES.dotabb>>
+<<GRALG.dotabb>>
+<<IXAGG.dotabb>>
 <<MONADWU.dotabb>>
 <<MONOID.dotabb>>
-<<MONOGEN.dotabb>>
+<<ORDFIN.dotabb>>
+<<RCAGG.dotabb>>
+<<ARR2CAT.dotabb>>
+<<BRAGG.dotabb>>
+<<CABMON.dotabb>>
+<<DIOPS.dotabb>>
+<<DLAGG.dotabb>>
+<<GROUP.dotabb>>
+<<LNAGG.dotabb>>
+<<OASGP.dotabb>>
+<<ORDMON.dotabb>>
+<<PSETCAT.dotabb>>
+<<PRQAGG.dotabb>>
+<<QUAGG.dotabb>>
+<<SETAGG.dotabb>>
+<<SKAGG.dotabb>>
+<<URAGG.dotabb>>
+<<ABELGRP.dotabb>>
+<<BTCAT.dotabb>>
+<<DIAGG.dotabb>>
+<<DQAGG.dotabb>>
+<<ELAGG.dotabb>>
+<<FLAGG.dotabb>>
+<<FAMONC.dotabb>>
+<<MDAGG.dotabb>>
+<<OAMON.dotabb>>
+<<PERMCAT.dotabb>>
+<<STAGG.dotabb>>
+<<TSETCAT.dotabb>>
+<<FDIVCAT.dotabb>>
+<<FSAGG.dotabb>>
+<<KDAGG.dotabb>>
+<<LZSTAGG.dotabb>>
+<<LMODULE.dotabb>>
+<<LSAGG.dotabb>>
 <<MSETAGG.dotabb>>
-<<MTSCAT.dotabb>>
-<<NAALG.dotabb>>
 <<NARNG.dotabb>>
+<<A1AGG.dotabb>>
+<<OCAMON.dotabb>>
+<<RSETCAT.dotabb>>
+<<RMODULE.dotabb>>
+<<RNG.dotabb>>
+<<BMODULE.dotabb>>
+<<BTAGG.dotabb>>
 <<NASRING.dotabb>>
 <<NTSCAT.dotabb>>
-<<NUMINT.dotabb>>
 <<OAGROUP.dotabb>>
-<<OAMON.dotabb>>
 <<OAMONS.dotabb>>
-<<OASGP.dotabb>>
-<<OC.dotabb>>
-<<OCAMON.dotabb>>
-<<ODECAT.dotabb>>
-<<OINTDOM.dotabb>>
-<<OM.dotabb>>
 <<OMSAGG.dotabb>>
-<<OPTCAT.dotabb>>
-<<ORDFIN.dotabb>>
-<<ORDMON.dotabb>>
+<<RING.dotabb>>
+<<SFRTCAT.dotabb>>
+<<SRAGG.dotabb>>
+<<TBAGG.dotabb>>
+<<VECTCAT.dotabb>>
+<<ALAGG.dotabb>>
+<<CHARNZ.dotabb>>
+<<CHARZ.dotabb>>
+<<COMRING.dotabb>>
+<<DIFRING.dotabb>>
+<<ENTIRER.dotabb>>
+<<FMCAT.dotabb>>
+<<LALG.dotabb>>
+<<LINEXP.dotabb>>
+<<MODULE.dotabb>>
 <<ORDRING.dotabb>>
-<<ORDSET.dotabb>>
-<<PADICCT.dotabb>>
-<<PATAB.dotabb>>
-<<PATMAB.dotabb>>
-<<PDECAT.dotabb>>
 <<PDRING.dotabb>>
-<<PERMCAT.dotabb>>
-<<PFECAT.dotabb>>
+<<PTCAT.dotabb>>
+<<RMATCAT.dotabb>>
+<<SNTSCAT.dotabb>>
+<<STRICAT.dotabb>>
+<<OREPCAT.dotabb>>
+<<XALG.dotabb>>
+<<ALGEBRA.dotabb>>
+<<DIFEXT.dotabb>>
+<<FLINEXP.dotabb>>
+<<LIECAT.dotabb>>
+<<LODOCAT.dotabb>>
+<<NAALG.dotabb>>
+<<VSPACE.dotabb>>
+<<XFALG.dotabb>>
+<<DIVRING.dotabb>>
+<<FINAALG.dotabb>>
+<<FLALG.dotabb>>
+<<INTDOM.dotabb>>
+<<MLO.dotabb>>
+<<OC.dotabb>>
+<<QUATCAT.dotabb>>
+<<SMATCAT.dotabb>>
+<<XPOLYC.dotabb>>
+<<AMR.dotabb>>
+<<FMTC.dotabb>>
+<<FRNAALG.dotabb>>
+<<GCDDOM.dotabb>>
+<<OINTDOM.dotabb>>
+<<FAMR.dotabb>>
+<<INTCAT.dotabb>>
+<<PSCAT.dotabb>>
 <<PID.dotabb>>
+<<UFD.dotabb>>
+<<EUCDOM.dotabb>>
+<<MTSCAT.dotabb>>
+<<PFECAT.dotabb>>
+<<UPSCAT.dotabb>>
+<<FIELD.dotabb>>
+<<INS.dotabb>>
+<<PADICCT.dotabb>>
 <<POLYCAT.dotabb>>
-<<PPCURVE.dotabb>>
-<<PSCURVE.dotabb>>
-<<PRIMCAT.dotabb>>
-<<PRQAGG.dotabb>>
-<<PSCAT.dotabb>>
-<<PSETCAT.dotabb>>
-<<PTCAT.dotabb>>
+<<UTSCAT.dotabb>>
+<<ACF.dotabb>>
+<<DPOLCAT.dotabb>>
+<<DIRPCAT.dotabb>>
+<<FPC.dotabb>>
+<<FINRALG.dotabb>>
+<<FS.dotabb>>
+<<MATCAT.dotabb>>
 <<QFCAT.dotabb>>
-<<QUAGG.dotabb>>
-<<RADCAT.dotabb>>
-<<RCAGG.dotabb>>
-<<REAL.dotabb>>
-<<RETRACT.dotabb>>
-<<RING.dotabb>>
-<<RMATCAT.dotabb>>
-<<RMODULE.dotabb>>
-<<RNG.dotabb>>
+<<RCFIELD.dotabb>>
 <<RNS.dotabb>>
 <<RPOLCAT.dotabb>>
-<<RSETCAT.dotabb>>
-<<SEGCAT.dotabb>>
-<<SEGXCAT.dotabb>>
-<<SETAGG.dotabb>>
-<<SETCAT.dotabb>>
-<<SEXCAT.dotabb>>
-<<SFRTCAT.dotabb>>
-<<SGROUP.dotabb>>
-<<SKAGG.dotabb>>
-<<SMATCAT.dotabb>>
-<<SPACEC.dotabb>>
-<<SPFCAT.dotabb>>
-<<SRAGG.dotabb>>
-<<STAGG.dotabb>>
-<<STEP.dotabb>>
-<<TRANFUN.dotabb>>
-<<TRIGCAT.dotabb>>
-<<TSETCAT.dotabb>>
-<<TYPE.dotabb>>
-<<TBAGG.dotabb>>
-<<UFD.dotabb>>
 <<ULSCAT.dotabb>>
-<<ULSCCAT.dotabb>>
-<<UPOLYC.dotabb>>
-<<UPSCAT.dotabb>>
 <<UPXSCAT.dotabb>>
-<<URAGG.dotabb>>
-<<UTSCAT.dotabb>>
-<<VECTCAT.dotabb>>
-<<VSPACE.dotabb>>
-<<XALG.dotabb>>
+<<UPOLYC.dotabb>>
+<<ACFS.dotabb>>
 <<XF.dotabb>>
-<<XFALG.dotabb>>
-<<XPOLYC.dotabb>>
+<<FFIELDC.dotabb>>
+<<FPS.dotabb>>
+<<FRAMALG.dotabb>>
+<<ULSCCAT.dotabb>>
+<<UPXSCCA.dotabb>>
+<<FAXF.dotabb>>
+<<MONOGEN.dotabb>>
+<<COMPCAT.dotabb>>
+<<FFCAT.dotabb>>
+
 }
 @
 <<dotfull>>=
@@ -66953,198 +70865,210 @@ digraph dotfull {
  node [shape=box, color=white, style=filled];
 
 <<CATEGORY.dotfull>>
-<<ABELGRP.dotfull>>
-<<ABELMON.dotfull>>
-<<ABELSG.dotfull>>
-<<ACF.dotfull>>
-<<ACFS.dotfull>>
-<<AGG.dotfull>>
 <<AHYP.dotfull>>
-<<ALAGG.dotfull>>
-<<ALGEBRA.dotfull>>
-<<AMR.dotfull>>
-<<ARR2CAT.dotfull>>
 <<ATRIG.dotfull>>
 <<ATTREG.dotfull>>
-<<A1AGG.dotfull>>
 <<BASTYPE.dotfull>>
-<<BGAGG.dotfull>>
-<<BMODULE.dotfull>>
-<<BRAGG.dotfull>>
-<<BTAGG.dotfull>>
-<<BTCAT.dotfull>>
-<<CABMON.dotfull>>
-<<CACHSET.dotfull>>
+<<KOERCE.dotfull>>
 <<CFCAT.dotfull>>
-<<CHARNZ.dotfull>>
-<<CHARZ.dotfull>>
-<<CLAGG.dotfull>>
-<<COMBOPC.dotfull>>
-<<COMRING.dotfull>>
-<<DIAGG.dotfull>>
-<<DIFEXT.dotfull>>
-<<DIOPS.dotfull>>
-<<DIRPCAT.dotfull>>
-<<DIVRING.dotfull>>
-<<DLAGG.dotfull>>
-<<DPOLCAT.dotfull>>
-<<DQAGG.dotfull>>
-<<DVARCAT.dotfull>>
-<<ELAGG.dotfull>>
+<<KONVERT.dotfull>>
 <<ELEMFUN.dotfull>>
 <<ELTAB.dotfull>>
+<<HYPCAT.dotfull>>
+<<IEVALAB.dotfull>>
+<<OM.dotfull>>
+<<PTRANFN.dotfull>>
+<<PATAB.dotfull>>
+<<PRIMCAT.dotfull>>
+<<RADCAT.dotfull>>
+<<RETRACT.dotfull>>
+<<SPFCAT.dotfull>>
+<<TRIGCAT.dotfull>>
+<<TYPE.dotfull>>
+<<AGG.dotfull>>
+<<COMBOPC.dotfull>>
 <<ELTAGG.dotfull>>
-<<ENTIRER.dotfull>>
-<<ES.dotfull>>
-<<EUCDOM.dotfull>>
 <<EVALAB.dotfull>>
-<<FAMONC.dotfull>>
-<<FAMR.dotfull>>
-<<FAXF.dotfull>>
-<<FDIVCAT.dotfull>>
-<<FEVALAB.dotfull>>
-<<FFCAT.dotfull>>
-<<FFIELDC.dotfull>>
-<<FIELD.dotfull>>
-<<FILECAT.dotfull>>
-<<FINAALG.dotfull>>
-<<FINITE.dotfull>>
-<<FINRALG.dotfull>>
-<<FLAGG.dotfull>>
-<<FLALG.dotfull>>
-<<FLINEXP.dotfull>>
-<<FMCAT.dotfull>>
-<<FMFUN.dotabb>>
-<<FMTC.dotfull>>
-<<FNCAT.dotfull>>
 <<FORTCAT.dotfull>>
+<<FRETRCT.dotfull>>
+<<FPATMAB.dotfull>>
+<<LOGIC.dotfull>>
+<<PPCURVE.dotfull>>
+<<PSCURVE.dotfull>>
+<<REAL.dotfull>>
+<<SEGCAT.dotfull>>
+<<SETCAT.dotfull>>
+<<TRANFUN.dotfull>>
+<<ABELSG.dotfull>>
 <<FORTFN.dotfull>>
 <<FMC.dotfull>>
-<<FPATMAB.dotfull>>
-<<FPC.dotfull>>
-<<FPS.dotfull>>
-<<FRAMALG.dotfull>>
-<<FRETRCT.dotfull>>
-<<FRNAALG.dotfull>>
-<<FS.dotfull>>
-<<FSAGG.dotfull>>
+<<FMFUN.dotfull>>
 <<FVC.dotfull>>
 <<FVFUN.dotfull>>
-<<GCDDOM.dotfull>>
-<<GRALG.dotfull>>
+<<FEVALAB.dotfull>>
+<<FILECAT.dotfull>>
+<<FINITE.dotfull>>
+<<FNCAT.dotfull>>
 <<GRMOD.dotfull>>
 <<HOAGG.dotfull>>
-<<HYPCAT.dotfull>>
 <<IDPC.dotfull>>
-<<IEVALAB.dotfull>>
-<<INS.dotfull>>
-<<INTCAT.dotfull>>
-<<INTDOM.dotfull>>
-<<IXAGG.dotfull>>
-<<KDAGG.dotfull>>
-<<KOERCE.dotfull>>
-<<KONVERT.dotfull>>
-<<LALG.dotfull>>
 <<LFCAT.dotfull>>
-<<LIECAT.dotfull>>
-<<LINEXP.dotfull>>
-<<LMODULE.dotfull>>
-<<LNAGG.dotfull>>
-<<LOGIC.dotfull>>
-<<LSAGG.dotfull>>
-<<LZSTAGG.dotfull>>
-<<MATCAT.dotfull>>
-<<MDAGG.dotfull>>
-<<MLO.dotfull>>
-<<MODULE.dotfull>>
 <<MONAD.dotfull>>
+<<NUMINT.dotfull>>
+<<OPTCAT.dotfull>>
+<<ODECAT.dotfull>>
+<<ORDSET.dotfull>>
+<<PDECAT.dotfull>>
+<<PATMAB.dotfull>>
+<<RRCC.dotfull>>
+<<SEGXCAT.dotfull>>
+<<SGROUP.dotfull>>
+<<SEXCAT.dotfull>>
+<<STEP.dotfull>>
+<<SPACEC.dotfull>>
+<<ABELMON.dotfull>>
+<<BGAGG.dotfull>>
+<<CACHSET.dotfull>>
+<<CLAGG.dotfull>>
+<<DVARCAT.dotfull>>
+<<ES.dotfull>>
+<<GRALG.dotfull>>
+<<IXAGG.dotfull>>
 <<MONADWU.dotfull>>
 <<MONOID.dotfull>>
-<<MONOGEN.dotfull>>
+<<ORDFIN.dotfull>>
+<<RCAGG.dotfull>>
+<<ARR2CAT.dotfull>>
+<<BRAGG.dotfull>>
+<<CABMON.dotfull>>
+<<DIOPS.dotfull>>
+<<DLAGG.dotfull>>
+<<GROUP.dotfull>>
+<<LNAGG.dotfull>>
+<<OASGP.dotfull>>
+<<ORDMON.dotfull>>
+<<PSETCAT.dotfull>>
+<<PRQAGG.dotfull>>
+<<QUAGG.dotfull>>
+<<SETAGG.dotfull>>
+<<SKAGG.dotfull>>
+<<URAGG.dotfull>>
+<<ABELGRP.dotfull>>
+<<BTCAT.dotfull>>
+<<DIAGG.dotfull>>
+<<DQAGG.dotfull>>
+<<ELAGG.dotfull>>
+<<FLAGG.dotfull>>
+<<FAMONC.dotfull>>
+<<MDAGG.dotfull>>
+<<OAMON.dotfull>>
+<<PERMCAT.dotfull>>
+<<STAGG.dotfull>>
+<<TSETCAT.dotfull>>
+<<FDIVCAT.dotfull>>
+<<FSAGG.dotfull>>
+<<KDAGG.dotfull>>
+<<LZSTAGG.dotfull>>
+<<LMODULE.dotfull>>
+<<LSAGG.dotfull>>
 <<MSETAGG.dotfull>>
-<<MTSCAT.dotfull>>
-<<NAALG.dotfull>>
 <<NARNG.dotfull>>
+<<A1AGG.dotfull>>
+<<OCAMON.dotfull>>
+<<RSETCAT.dotfull>>
+<<RMODULE.dotfull>>
+<<RNG.dotfull>>
+<<BMODULE.dotfull>>
+<<BTAGG.dotfull>>
 <<NASRING.dotfull>>
 <<NTSCAT.dotfull>>
-<<NUMINT.dotfull>>
 <<OAGROUP.dotfull>>
-<<OAMON.dotfull>>
-<<OAMONS.dotabb>>
-<<OASGP.dotfull>>
-<<OC.dotfull>>
-<<OCAMON.dotfull>>
-<<ODECAT.dotfull>>
-<<OINTDOM.dotfull>>
-<<OM.dotfull>>
+<<OAMONS.dotfull>>
 <<OMSAGG.dotfull>>
-<<OPTCAT.dotfull>>
-<<ORDFIN.dotfull>>
-<<ORDMON.dotfull>>
+<<RING.dotfull>>
+<<SFRTCAT.dotfull>>
+<<SRAGG.dotfull>>
+<<TBAGG.dotfull>>
+<<VECTCAT.dotfull>>
+<<ALAGG.dotfull>>
+<<CHARNZ.dotfull>>
+<<CHARZ.dotfull>>
+<<COMRING.dotfull>>
+<<DIFRING.dotfull>>
+<<ENTIRER.dotfull>>
+<<FMCAT.dotfull>>
+<<LALG.dotfull>>
+<<LINEXP.dotfull>>
+<<MODULE.dotfull>>
 <<ORDRING.dotfull>>
-<<ORDSET.dotfull>>
-<<PADICCT.dotfull>>
-<<PATAB.dotfull>>
-<<PATMAB.dotfull>>
-<<PDECAT.dotfull>>
 <<PDRING.dotfull>>
-<<PERMCAT.dotfull>>
-<<PFECAT.dotfull>>
+<<PTCAT.dotfull>>
+<<RMATCAT.dotfull>>
+<<SNTSCAT.dotfull>>
+<<STRICAT.dotfull>>
+<<OREPCAT.dotfull>>
+<<XALG.dotfull>>
+<<ALGEBRA.dotfull>>
+<<DIFEXT.dotfull>>
+<<FLINEXP.dotfull>>
+<<LIECAT.dotfull>>
+<<LODOCAT.dotfull>>
+<<NAALG.dotfull>>
+<<VSPACE.dotfull>>
+<<XFALG.dotfull>>
+<<DIVRING.dotfull>>
+<<FINAALG.dotfull>>
+<<FLALG.dotfull>>
+<<INTDOM.dotfull>>
+<<MLO.dotfull>>
+<<OC.dotfull>>
+<<QUATCAT.dotfull>>
+<<SMATCAT.dotfull>>
+<<XPOLYC.dotfull>>
+<<AMR.dotfull>>
+<<FMTC.dotfull>>
+<<FRNAALG.dotfull>>
+<<GCDDOM.dotfull>>
+<<OINTDOM.dotfull>>
+<<FAMR.dotfull>>
+<<INTCAT.dotfull>>
+<<PSCAT.dotfull>>
 <<PID.dotfull>>
+<<UFD.dotfull>>
+<<EUCDOM.dotfull>>
+<<MTSCAT.dotfull>>
+<<PFECAT.dotfull>>
+<<UPSCAT.dotfull>>
+<<FIELD.dotfull>>
+<<INS.dotfull>>
+<<PADICCT.dotfull>>
 <<POLYCAT.dotfull>>
-<<PPCURVE.dotfull>>
-<<PSCURVE.dotfull>>
-<<PRIMCAT.dotfull>>
-<<PRQAGG.dotfull>>
-<<PSCAT.dotfull>>
-<<PSETCAT.dotfull>>
-<<PTCAT.dotfull>>
+<<UTSCAT.dotfull>>
+<<ACF.dotfull>>
+<<DPOLCAT.dotfull>>
+<<DIRPCAT.dotfull>>
+<<FPC.dotfull>>
+<<FINRALG.dotfull>>
+<<FS.dotfull>>
+<<MATCAT.dotfull>>
 <<QFCAT.dotfull>>
-<<QUAGG.dotfull>>
-<<RADCAT.dotfull>>
-<<RCAGG.dotfull>>
-<<REAL.dotfull>>
-<<RETRACT.dotfull>>
-<<RING.dotfull>>
-<<RMATCAT.dotfull>>
-<<RMODULE.dotfull>>
-<<RNG.dotfull>>
+<<RCFIELD.dotfull>>
 <<RNS.dotfull>>
 <<RPOLCAT.dotfull>>
-<<RSETCAT.dotfull>>
-<<SEGCAT.dotfull>>
-<<SEGXCAT.dotfull>>
-<<SETAGG.dotfull>>
-<<SETCAT.dotfull>>
-<<SEXCAT.dotfull>>
-<<SFRTCAT.dotfull>>
-<<SGROUP.dotfull>>
-<<SKAGG.dotfull>>
-<<SMATCAT.dotfull>>
-<<SPACEC.dotfull>>
-<<SPFCAT.dotfull>>
-<<SRAGG.dotfull>>
-<<STAGG.dotfull>>
-<<STEP.dotfull>>
-<<TRANFUN.dotfull>>
-<<TRIGCAT.dotfull>>
-<<TSETCAT.dotfull>>
-<<TYPE.dotfull>>
-<<TBAGG.dotfull>>
-<<UFD.dotfull>>
 <<ULSCAT.dotfull>>
-<<ULSCCAT.dotfull>>
-<<UPOLYC.dotfull>>
-<<UPSCAT.dotfull>>
 <<UPXSCAT.dotfull>>
-<<URAGG.dotfull>>
-<<UTSCAT.dotfull>>
-<<VECTCAT.dotfull>>
-<<VSPACE.dotfull>>
-<<XALG.dotfull>>
+<<UPOLYC.dotfull>>
+<<ACFS.dotfull>>
 <<XF.dotfull>>
-<<XFALG.dotfull>>
-<<XPOLYC.dotfull>>
+<<FFIELDC.dotfull>>
+<<FPS.dotfull>>
+<<FRAMALG.dotfull>>
+<<ULSCCAT.dotfull>>
+<<UPXSCCA.dotfull>>
+<<FAXF.dotfull>>
+<<MONOGEN.dotfull>>
+<<COMPCAT.dotfull>>
+<<FFCAT.dotfull>>
 }
 @
 \eject
@@ -67159,6 +71083,23 @@ Academic Press, New York, 1966
 Lecture Notes Univ. Duesseldorf 1991
 \bibitem{6} J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
 AXIOM Technical Report Series, ATR/5 NP2522.
+\bibitem{7} R. Rioboo,
+{\sl Real Algebraic Closure of an ordered Field : Implementation in Axiom.},
+In proceedings of the ISSAC'92 Conference, Berkeley 1992 pp. 206-215.
+\bibitem{8} Z. Ligatsikas, R. Rioboo, M. F. Roy 
+{\sl Generic computation of the real closure of an ordered field.},
+In Mathematics and Computers in Simulation Volume 42, Issue 4-6,
+November 1996.
+\bibitem{9} D. LAZARD ``A new method for solving algebraic systems of 
+positive dimension'' Discr. App. Math. 33:147-160,1991
+\bibitem{10} P. AUBRY, D. LAZARD and M. MORENO MAZA ``On the Theories
+of Triangular Sets'' Journal of Symbol. Comp. (to appear)
+\bibitem{11} M. MORENO MAZA and R. RIOBOO ``Computations of gcd over
+algebraic towers of simple extensions'' In proceedings of AAECC11
+Paris, 1995.
+\bibitem{12} M. MORENO MAZA ``Calculs de pgcd au-dessus des tours
+d'extensions simples et resolution des systemes d'equations
+algebriques'' These, Universite P.etM. Curie, Paris, 1997.
 \end{thebibliography}
 \printindex
 \end{document}
diff --git a/books/ps/v102complexcategory.ps b/books/ps/v102complexcategory.ps
new file mode 100644
index 0000000..214a5b9
--- /dev/null
+++ b/books/ps/v102complexcategory.ps
@@ -0,0 +1,611 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 858 152
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 858 152
+%%PageOrientation: Portrait
+gsave
+36 36 822 116 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+820 114 lineto
+820 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+820 114 lineto
+820 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% ComplexCategory(R:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 535 108 moveto
+291 108 lineto
+291 72 lineto
+535 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 535 108 moveto
+291 108 lineto
+291 72 lineto
+535 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+299 85 moveto
+(ComplexCategory\(R:CommutativeRing\))
+[9.36 6.96 10.56 6.96 3.84 5.76 6.96 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 9.36 3.84 9.36 6.96 10.8 10.8 6.96 4.08 6.24 3.84 3.84 6.48 6.24 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% MONOGEN...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 98 36 moveto
+0 36 lineto
+0 0 lineto
+98 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 98 36 moveto
+0 36 lineto
+0 0 lineto
+98 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 13 moveto
+(MONOGEN...)
+[12.48 10.08 9.84 10.08 10.08 8.64 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->MONOGEN...
+newpath 292 72 moveto
+239 63 174 51 108 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 108 33 moveto
+98 34 lineto
+107 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 108 33 moveto
+98 34 lineto
+107 39 lineto
+closepath
+stroke
+end grestore
+% FRETRCT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 202 36 moveto
+116 36 lineto
+116 0 lineto
+202 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 202 36 moveto
+116 36 lineto
+116 0 lineto
+202 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+123 13 moveto
+(FRETRCT...)
+[7.68 9.36 8.64 8.64 8.88 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->FRETRCT...
+newpath 341 72 moveto
+304 63 260 51 212 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 213 33 moveto
+202 33 lineto
+211 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 213 33 moveto
+202 33 lineto
+211 39 lineto
+closepath
+stroke
+end grestore
+% DIFEXT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+220 36 lineto
+220 0 lineto
+296 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+220 36 lineto
+220 0 lineto
+296 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+227 13 moveto
+(DIFEXT...)
+[10.08 4.56 7.68 8.64 10.08 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->DIFEXT...
+newpath 374 72 moveto
+353 62 327 50 305 40 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 307 37 moveto
+296 36 lineto
+304 43 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 307 37 moveto
+296 36 lineto
+304 43 lineto
+closepath
+stroke
+end grestore
+% FEVALAB...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 404 36 moveto
+314 36 lineto
+314 0 lineto
+404 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 404 36 moveto
+314 36 lineto
+314 0 lineto
+404 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+322 13 moveto
+(FEVALAB...)
+[7.68 8.64 8.4 10.08 8.64 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->FEVALAB...
+newpath 399 72 moveto
+393 64 385 53 378 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 381 42 moveto
+372 36 lineto
+375 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 381 42 moveto
+372 36 lineto
+375 46 lineto
+closepath
+stroke
+end grestore
+% FPATMAB...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 514 36 moveto
+422 36 lineto
+422 0 lineto
+514 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 514 36 moveto
+422 36 lineto
+422 0 lineto
+514 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+430 13 moveto
+(FPATMAB...)
+[7.68 6.48 9.36 8.64 12.48 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->FPATMAB...
+newpath 427 72 moveto
+433 64 441 53 448 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 451 46 moveto
+454 36 lineto
+445 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 451 46 moveto
+454 36 lineto
+445 42 lineto
+closepath
+stroke
+end grestore
+% PATAB...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 604 36 moveto
+532 36 lineto
+532 0 lineto
+604 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 604 36 moveto
+532 36 lineto
+532 0 lineto
+604 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+540 13 moveto
+(PATAB...)
+[6.48 9.36 7.92 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->PATAB...
+newpath 452 72 moveto
+474 62 500 50 523 39 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 524 42 moveto
+532 35 lineto
+521 36 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 524 42 moveto
+532 35 lineto
+521 36 lineto
+closepath
+stroke
+end grestore
+% FLINEXP...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 704 36 moveto
+622 36 lineto
+622 0 lineto
+704 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 704 36 moveto
+622 36 lineto
+622 0 lineto
+704 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+629 13 moveto
+(FLINEXP...)
+[7.68 8.64 4.56 10.08 8.64 10.08 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->FLINEXP...
+newpath 485 72 moveto
+521 63 565 51 612 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 613 39 moveto
+622 33 lineto
+611 33 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 613 39 moveto
+622 33 lineto
+611 33 lineto
+closepath
+stroke
+end grestore
+% COMRING...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 814 36 moveto
+722 36 lineto
+722 0 lineto
+814 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 814 36 moveto
+722 36 lineto
+722 0 lineto
+814 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+729 13 moveto
+(COMRING...)
+[9.12 10.08 12.48 9.36 4.56 9.84 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% ComplexCategory(R:CommutativeRing)->COMRING...
+newpath 534 72 moveto
+586 63 649 52 712 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 713 39 moveto
+722 33 lineto
+711 33 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 713 39 moveto
+722 33 lineto
+711 33 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102eltab.ps b/books/ps/v102eltab.ps
index 9902751..f637e59 100644
--- a/books/ps/v102eltab.ps
+++ b/books/ps/v102eltab.ps
@@ -206,11 +206,6 @@ stroke
 0.000 0.000 0.000 graphcolor
 14.00 /Times-Roman set_font
 % Eltable(a:SetCategory,b:Type)
-[ /Rect [ 0 72 186 108 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
@@ -237,11 +232,6 @@ xshow
 end grestore
 end grestore
 % Category
-[ /Rect [ 59 0 127 36 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
diff --git a/books/ps/v102linearordinarydifferentialoperatorcategory.ps b/books/ps/v102linearordinarydifferentialoperatorcategory.ps
new file mode 100644
index 0000000..de00540
--- /dev/null
+++ b/books/ps/v102linearordinarydifferentialoperatorcategory.ps
@@ -0,0 +1,1316 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 797 512
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 797 512
+%%PageOrientation: Portrait
+gsave
+36 36 761 476 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+759 474 lineto
+759 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+759 474 lineto
+759 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% LinearOrdinaryDifferentialOperatorCategory(a:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 426 468 moveto
+110 468 lineto
+110 432 lineto
+426 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 426 468 moveto
+110 468 lineto
+110 432 lineto
+426 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+118 445 moveto
+(LinearOrdinaryDifferentialOperatorCategory\(a:Ring\))
+[8.64 3.84 6.96 6.24 6.24 4.8 10.08 4.56 6.96 3.84 6.96 6.24 5.04 6.96 10.08 3.84 4.56 4.08 6.24 4.8 6.24 6.96 3.84 3.84 6.24 3.84 10.08 6.96 6.24 4.8 6.24 3.84 6.96 4.8 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% Eltable(a:Ring,b:Ring)
+[ /Rect [ 71 360 215 396 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=ELTAB) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 215 396 moveto
+71 396 lineto
+71 360 lineto
+215 360 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 215 396 moveto
+71 396 lineto
+71 360 lineto
+215 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+79 373 moveto
+(Eltable\(a:Ring,b:Ring\))
+[8.64 3.84 4.08 6.24 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% LinearOrdinaryDifferentialOperatorCategory(a:Ring)->Eltable(a:Ring,b:Ring)
+newpath 236 432 moveto
+220 423 200 411 183 401 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 184 398 moveto
+174 396 lineto
+181 404 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 184 398 moveto
+174 396 lineto
+181 404 lineto
+closepath
+stroke
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 528 396 moveto
+258 396 lineto
+258 360 lineto
+528 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 528 396 moveto
+258 396 lineto
+258 360 lineto
+528 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+265 373 moveto
+(UnivariateSkewPolynomialCategory\(R:Ring\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.68 6.72 5.76 10.08 7.44 6.96 3.6 6.96 6.96 6.96 10.8 3.84 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 9.36 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% LinearOrdinaryDifferentialOperatorCategory(a:Ring)->UnivariateSkewPolynomialCategory(R:Ring)
+newpath 300 432 moveto
+316 423 336 411 353 401 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 355 404 moveto
+362 396 lineto
+352 398 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 355 404 moveto
+362 396 lineto
+352 398 lineto
+closepath
+stroke
+end grestore
+% Eltable(a:SetCategory,b:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 186 324 moveto
+0 324 lineto
+0 288 lineto
+186 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 186 324 moveto
+0 324 lineto
+0 288 lineto
+186 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 301 moveto
+(Eltable\(a:SetCategory,b:Type\))
+[8.64 3.84 4.08 6.24 6.96 3.84 6.24 4.56 6.24 3.84 7.68 6 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6 3.6 6.96 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% Eltable(a:Ring,b:Ring)->Eltable(a:SetCategory,b:Type)
+newpath 130 360 moveto
+125 352 118 342 112 332 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 115 330 moveto
+106 324 lineto
+109 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 115 330 moveto
+106 324 lineto
+109 334 lineto
+closepath
+stroke
+end grestore
+% BiModule(a:Ring,b:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 626 324 moveto
+464 324 lineto
+464 288 lineto
+626 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 626 324 moveto
+464 324 lineto
+464 288 lineto
+626 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+472 301 moveto
+(BiModule\(a:Ring,b:Ring\))
+[9.36 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->BiModule(a:Ring,b:Ring)
+newpath 431 360 moveto
+451 350 476 339 498 328 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 499 331 moveto
+507 324 lineto
+496 325 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 499 331 moveto
+507 324 lineto
+496 325 lineto
+closepath
+stroke
+end grestore
+% FullyRetractableTo(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 374 324 moveto
+204 324 lineto
+204 288 lineto
+374 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 374 324 moveto
+204 324 lineto
+204 288 lineto
+374 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+212 301 moveto
+(FullyRetractableTo\(a:Ring\))
+[7.44 6.96 3.84 3.6 6.96 9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->FullyRetractableTo(a:Ring)
+newpath 367 360 moveto
+354 351 338 340 324 330 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 325 327 moveto
+315 324 lineto
+321 332 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 325 327 moveto
+315 324 lineto
+321 332 lineto
+closepath
+stroke
+end grestore
+% Ring()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 446 324 moveto
+392 324 lineto
+392 288 lineto
+446 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 446 324 moveto
+392 324 lineto
+392 288 lineto
+446 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+400 301 moveto
+(Ring\(\))
+[9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->Ring()
+newpath 400 360 moveto
+403 352 406 343 409 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 412 335 moveto
+412 324 lineto
+406 333 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 412 335 moveto
+412 324 lineto
+406 333 lineto
+closepath
+stroke
+end grestore
+% Category
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 200 108 moveto
+132 108 lineto
+132 72 lineto
+200 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 200 108 moveto
+132 108 lineto
+132 72 lineto
+200 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+140 85 moveto
+(Category)
+[9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+xshow
+end grestore
+end grestore
+% Eltable(a:SetCategory,b:Type)->Category
+newpath 93 288 moveto
+93 257 97 192 119 144 curveto
+124 133 131 124 139 115 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 141 118 moveto
+146 108 lineto
+136 113 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 141 118 moveto
+146 108 lineto
+136 113 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 599 252 moveto
+469 252 lineto
+469 216 lineto
+599 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 599 252 moveto
+469 252 lineto
+469 216 lineto
+599 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+477 229 moveto
+(LeftModule\(a:Ring\))
+[8.64 6.24 4.8 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% BiModule(a:Ring,b:Ring)->LeftModule(a:Ring)
+newpath 542 288 moveto
+541 280 539 271 538 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 541 262 moveto
+537 252 lineto
+535 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 541 262 moveto
+537 252 lineto
+535 262 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 753 252 moveto
+617 252 lineto
+617 216 lineto
+753 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 753 252 moveto
+617 252 lineto
+617 216 lineto
+753 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+624 229 moveto
+(RightModule\(a:Ring\))
+[9.36 3.84 6.96 6.96 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% BiModule(a:Ring,b:Ring)->RightModule(a:Ring)
+newpath 580 288 moveto
+599 279 622 267 641 257 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 643 260 moveto
+650 252 lineto
+640 254 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 643 260 moveto
+650 252 lineto
+640 254 lineto
+closepath
+stroke
+end grestore
+% FullyRetractableTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 291 252 moveto
+121 252 lineto
+121 216 lineto
+291 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 291 252 moveto
+121 252 lineto
+121 216 lineto
+291 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+129 229 moveto
+(FullyRetractableTo\(a:Type\))
+[7.44 6.96 3.84 3.6 6.96 9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% FullyRetractableTo(a:Ring)->FullyRetractableTo(a:Type)
+newpath 268 288 moveto
+258 279 245 268 234 259 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 236 256 moveto
+226 252 lineto
+231 261 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 236 256 moveto
+226 252 lineto
+231 261 lineto
+closepath
+stroke
+end grestore
+% Rng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 451 252 moveto
+397 252 lineto
+397 216 lineto
+451 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 451 252 moveto
+397 252 lineto
+397 216 lineto
+451 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+407 229 moveto
+(Rng\(\))
+[9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Rng()
+newpath 420 288 moveto
+421 280 421 271 422 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 425 262 moveto
+423 252 lineto
+419 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 425 262 moveto
+423 252 lineto
+419 262 lineto
+closepath
+stroke
+end grestore
+% Monoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 379 252 moveto
+309 252 lineto
+309 216 lineto
+379 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 379 252 moveto
+309 252 lineto
+309 216 lineto
+379 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+316 229 moveto
+(Monoid\(\))
+[12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Monoid()
+newpath 400 288 moveto
+391 279 380 269 370 259 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 373 257 moveto
+363 252 lineto
+368 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 373 257 moveto
+363 252 lineto
+368 262 lineto
+closepath
+stroke
+end grestore
+% Ring()->LeftModule(a:Ring)
+newpath 446 289 moveto
+461 280 480 268 496 257 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 498 260 moveto
+505 252 lineto
+495 254 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 498 260 moveto
+505 252 lineto
+495 254 lineto
+closepath
+stroke
+end grestore
+% RetractableTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 268 180 moveto
+128 180 lineto
+128 144 lineto
+268 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 268 180 moveto
+128 180 lineto
+128 144 lineto
+268 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+135 157 moveto
+(RetractableTo\(a:Type\))
+[9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% FullyRetractableTo(a:Type)->RetractableTo(a:Type)
+newpath 204 216 moveto
+203 208 202 199 201 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 204 190 moveto
+200 180 lineto
+198 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 204 190 moveto
+200 180 lineto
+198 190 lineto
+closepath
+stroke
+end grestore
+% RetractableTo(a:Type)->Category
+newpath 190 144 moveto
+186 136 182 126 178 117 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 181 116 moveto
+174 108 lineto
+175 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 181 116 moveto
+174 108 lineto
+175 119 lineto
+closepath
+stroke
+end grestore
+% AbelianGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 587 108 moveto
+481 108 lineto
+481 72 lineto
+587 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 587 108 moveto
+481 108 lineto
+481 72 lineto
+587 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+489 85 moveto
+(AbelianGroup\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 10.08 4.8 6.96 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Rng()->AbelianGroup()
+newpath 428 216 moveto
+434 197 445 166 462 144 curveto
+471 133 482 122 494 114 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 496 117 moveto
+502 108 lineto
+492 111 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 496 117 moveto
+502 108 lineto
+492 111 lineto
+closepath
+stroke
+end grestore
+% SemiGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 392 180 moveto
+302 180 lineto
+302 144 lineto
+392 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 392 180 moveto
+302 180 lineto
+302 144 lineto
+392 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+310 157 moveto
+(SemiGroup\(\))
+[7.68 6.24 10.8 3.84 10.08 4.8 6.96 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Rng()->SemiGroup()
+newpath 405 216 moveto
+395 207 384 197 374 187 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 376 184 moveto
+366 180 lineto
+371 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 376 184 moveto
+366 180 lineto
+371 189 lineto
+closepath
+stroke
+end grestore
+% Monoid()->SemiGroup()
+newpath 345 216 moveto
+346 208 346 199 346 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 350 190 moveto
+346 180 lineto
+343 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 350 190 moveto
+346 180 lineto
+343 190 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 597 180 moveto
+471 180 lineto
+471 144 lineto
+597 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 597 180 moveto
+471 180 lineto
+471 144 lineto
+597 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+479 157 moveto
+(LeftModule\(a:Rng\))
+[8.64 6.24 4.8 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% LeftModule(a:Ring)->LeftModule(a:Rng)
+newpath 534 216 moveto
+534 208 534 199 534 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 538 190 moveto
+534 180 lineto
+531 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 538 190 moveto
+534 180 lineto
+531 190 lineto
+closepath
+stroke
+end grestore
+% CABMON...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 529 36 moveto
+441 36 lineto
+441 0 lineto
+529 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 529 36 moveto
+441 36 lineto
+441 0 lineto
+529 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+449 13 moveto
+(CABMON...)
+[9.12 10.08 9.36 12.48 10.08 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->CABMON...
+newpath 522 72 moveto
+516 64 509 54 503 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 506 42 moveto
+497 36 lineto
+500 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 506 42 moveto
+497 36 lineto
+500 46 lineto
+closepath
+stroke
+end grestore
+% REPDB...
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 619 36 moveto
+547 36 lineto
+547 0 lineto
+619 0 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 619 36 moveto
+547 36 lineto
+547 0 lineto
+619 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+554 13 moveto
+(REPDB...)
+[9.36 8.64 7.68 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->REPDB...
+newpath 546 72 moveto
+552 64 559 54 565 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 568 46 moveto
+571 36 lineto
+562 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 568 46 moveto
+571 36 lineto
+562 42 lineto
+closepath
+stroke
+end grestore
+% SETCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 420 108 moveto
+342 108 lineto
+342 72 lineto
+420 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 420 108 moveto
+342 108 lineto
+342 72 lineto
+420 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+350 85 moveto
+(SETCAT...)
+[7.68 8.64 8.64 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SemiGroup()->SETCAT...
+newpath 356 144 moveto
+360 136 364 126 369 117 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 372 119 moveto
+373 108 lineto
+366 116 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 372 119 moveto
+373 108 lineto
+366 116 lineto
+closepath
+stroke
+end grestore
+% REPSQ...
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 324 108 moveto
+254 108 lineto
+254 72 lineto
+324 72 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 324 108 moveto
+254 108 lineto
+254 72 lineto
+324 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+261 85 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SemiGroup()->REPSQ...
+newpath 332 144 moveto
+325 135 317 125 309 116 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 312 114 moveto
+303 108 lineto
+306 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 312 114 moveto
+303 108 lineto
+306 118 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 750 180 moveto
+616 180 lineto
+616 144 lineto
+750 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 750 180 moveto
+616 180 lineto
+616 144 lineto
+750 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+624 157 moveto
+(RightModule\(a:Rng\))
+[9.36 3.84 6.96 6.96 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% RightModule(a:Ring)->RightModule(a:Rng)
+newpath 684 216 moveto
+684 208 684 199 684 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 687 190 moveto
+683 180 lineto
+681 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 687 190 moveto
+683 180 lineto
+681 190 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->AbelianGroup()
+newpath 645 144 moveto
+625 134 601 123 580 112 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 582 109 moveto
+571 108 lineto
+579 115 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 582 109 moveto
+571 108 lineto
+579 115 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->AbelianGroup()
+newpath 534 144 moveto
+534 136 534 127 534 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 538 118 moveto
+534 108 lineto
+531 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 538 118 moveto
+534 108 lineto
+531 118 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102partialtranscendentalfunctions.ps b/books/ps/v102partialtranscendentalfunctions.ps
new file mode 100644
index 0000000..53ac938
--- /dev/null
+++ b/books/ps/v102partialtranscendentalfunctions.ps
@@ -0,0 +1,289 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 432 152
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 432 152
+%%PageOrientation: Portrait
+gsave
+36 36 396 116 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+394 114 lineto
+394 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+394 114 lineto
+394 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% PartialTranscendentalFunctions(TranscendentalFunctionCategory)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 388 108 moveto
+0 108 lineto
+0 72 lineto
+388 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 388 108 moveto
+0 108 lineto
+0 72 lineto
+388 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 85 moveto
+(PartialTranscendentalFunctions\(TranscendentalFunctionCategory\))
+[7.44 6.24 5.04 3.84 3.84 6.24 3.84 7.92 4.8 6.24 6.96 5.52 6.24 6.24 6.96 6.96 6.24 6.96 4.08 6.24 3.84 7.44 6.96 6.96 6.24 3.84 3.84 6.96 6.96 5.52 4.56 7.92 4.8 6.24 6.96 5.52 6.24 6.24 6.96 6.96 6.24 6.96 4.08 6.24 3.84 7.44 6.96 6.96 6.24 3.84 3.84 6.96 6.96 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56]
+xshow
+end grestore
+end grestore
+% Category
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 228 36 moveto
+160 36 lineto
+160 0 lineto
+228 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 228 36 moveto
+160 36 lineto
+160 0 lineto
+228 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+168 13 moveto
+(Category)
+[9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+xshow
+end grestore
+end grestore
+% PartialTranscendentalFunctions(TranscendentalFunctionCategory)->Category
+newpath 194 72 moveto
+194 64 194 55 194 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 198 46 moveto
+194 36 lineto
+191 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 198 46 moveto
+194 36 lineto
+191 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102quaternioncategory.ps b/books/ps/v102quaternioncategory.ps
new file mode 100644
index 0000000..c6f68ba
--- /dev/null
+++ b/books/ps/v102quaternioncategory.ps
@@ -0,0 +1,473 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 544 152
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 544 152
+%%PageOrientation: Portrait
+gsave
+36 36 508 116 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+506 114 lineto
+506 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+506 114 lineto
+506 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% QuaternionCategory(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 377 108 moveto
+125 108 lineto
+125 72 lineto
+377 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 377 108 moveto
+125 108 lineto
+125 72 lineto
+377 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+132 85 moveto
+(QuaternionCategory\(a:CommutativeRing\))
+[10.08 6.96 6.24 3.84 6.24 5.04 6.96 3.84 6.96 6.96 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 6.96 10.8 10.8 6.96 4.08 6.24 3.84 3.84 6.48 6.24 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% ALGEBRA...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 94 36 moveto
+0 36 lineto
+0 0 lineto
+94 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 94 36 moveto
+0 36 lineto
+0 0 lineto
+94 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 13 moveto
+(ALGEBRA...)
+[10.08 8.64 10.08 8.64 9.36 9.36 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% QuaternionCategory(a:CommutativeRing)->ALGEBRA...
+newpath 200 72 moveto
+170 62 134 49 104 38 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 105 35 moveto
+94 35 lineto
+103 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 105 35 moveto
+94 35 lineto
+103 41 lineto
+closepath
+stroke
+end grestore
+% DIFEXT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 188 36 moveto
+112 36 lineto
+112 0 lineto
+188 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 188 36 moveto
+112 36 lineto
+112 0 lineto
+188 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+119 13 moveto
+(DIFEXT...)
+[10.08 4.56 7.68 8.64 10.08 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% QuaternionCategory(a:CommutativeRing)->DIFEXT...
+newpath 226 72 moveto
+214 63 198 52 184 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 185 39 moveto
+175 36 lineto
+181 44 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 185 39 moveto
+175 36 lineto
+181 44 lineto
+closepath
+stroke
+end grestore
+% FEVALAB...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+206 36 lineto
+206 0 lineto
+296 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+206 36 lineto
+206 0 lineto
+296 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+214 13 moveto
+(FEVALAB...)
+[7.68 8.64 8.4 10.08 8.64 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% QuaternionCategory(a:CommutativeRing)->FEVALAB...
+newpath 251 72 moveto
+251 64 251 55 251 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 255 46 moveto
+251 36 lineto
+248 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 255 46 moveto
+251 36 lineto
+248 46 lineto
+closepath
+stroke
+end grestore
+% FLINEXP...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 396 36 moveto
+314 36 lineto
+314 0 lineto
+396 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 396 36 moveto
+314 36 lineto
+314 0 lineto
+396 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+321 13 moveto
+(FLINEXP...)
+[7.68 8.64 4.56 10.08 8.64 10.08 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% QuaternionCategory(a:CommutativeRing)->FLINEXP...
+newpath 277 72 moveto
+290 63 306 52 320 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 323 44 moveto
+329 36 lineto
+319 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 323 44 moveto
+329 36 lineto
+319 39 lineto
+closepath
+stroke
+end grestore
+% FRETRCT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 500 36 moveto
+414 36 lineto
+414 0 lineto
+500 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 500 36 moveto
+414 36 lineto
+414 0 lineto
+500 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+421 13 moveto
+(FRETRCT...)
+[7.68 9.36 8.64 8.64 8.88 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% QuaternionCategory(a:CommutativeRing)->FRETRCT...
+newpath 303 72 moveto
+334 61 373 48 404 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 405 39 moveto
+414 33 lineto
+403 33 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 405 39 moveto
+414 33 lineto
+403 33 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102realclosedfield.ps b/books/ps/v102realclosedfield.ps
new file mode 100644
index 0000000..2b9c1b6
--- /dev/null
+++ b/books/ps/v102realclosedfield.ps
@@ -0,0 +1,565 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 736 152
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 736 152
+%%PageOrientation: Portrait
+gsave
+36 36 700 116 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+698 114 lineto
+698 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+698 114 lineto
+698 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% RealClosedField()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 406 108 moveto
+288 108 lineto
+288 72 lineto
+406 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 406 108 moveto
+288 108 lineto
+288 72 lineto
+406 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+296 85 moveto
+(RealClosedField\(\))
+[9.12 6.24 6.24 3.84 9.36 3.84 6.96 5.52 6.24 6.96 7.44 3.84 6.24 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% ALGEBRA...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 94 36 moveto
+0 36 lineto
+0 0 lineto
+94 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 94 36 moveto
+0 36 lineto
+0 0 lineto
+94 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 13 moveto
+(ALGEBRA...)
+[10.08 8.64 10.08 8.64 9.36 9.36 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->ALGEBRA...
+newpath 288 78 moveto
+240 68 172 54 104 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 105 33 moveto
+94 33 lineto
+103 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 105 33 moveto
+94 33 lineto
+103 39 lineto
+closepath
+stroke
+end grestore
+% CHARZ...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 186 36 moveto
+112 36 lineto
+112 0 lineto
+186 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 186 36 moveto
+112 36 lineto
+112 0 lineto
+186 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+119 13 moveto
+(CHARZ...)
+[9.36 10.08 10.08 9.36 8.64 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->CHARZ...
+newpath 295 72 moveto
+268 63 234 50 196 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 197 33 moveto
+186 33 lineto
+195 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 197 33 moveto
+186 33 lineto
+195 39 lineto
+closepath
+stroke
+end grestore
+% COMRING...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+204 36 lineto
+204 0 lineto
+296 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 296 36 moveto
+204 36 lineto
+204 0 lineto
+296 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+211 13 moveto
+(COMRING...)
+[9.12 10.08 12.48 9.36 4.56 9.84 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->COMRING...
+newpath 323 72 moveto
+311 63 296 52 282 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 284 39 moveto
+274 36 lineto
+280 45 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 284 39 moveto
+274 36 lineto
+280 45 lineto
+closepath
+stroke
+end grestore
+% FIELD...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 380 36 moveto
+314 36 lineto
+314 0 lineto
+380 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 380 36 moveto
+314 36 lineto
+314 0 lineto
+380 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+321 13 moveto
+(FIELD...)
+[7.68 4.56 8.64 8.64 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->FIELD...
+newpath 347 72 moveto
+347 64 347 55 347 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 351 46 moveto
+347 36 lineto
+344 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 351 46 moveto
+347 36 lineto
+344 46 lineto
+closepath
+stroke
+end grestore
+% FRETRCT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 484 36 moveto
+398 36 lineto
+398 0 lineto
+484 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 484 36 moveto
+398 36 lineto
+398 0 lineto
+484 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+405 13 moveto
+(FRETRCT...)
+[7.68 9.36 8.64 8.64 8.88 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->FRETRCT...
+newpath 371 72 moveto
+382 63 397 52 410 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 412 45 moveto
+418 36 lineto
+408 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 412 45 moveto
+418 36 lineto
+408 39 lineto
+closepath
+stroke
+end grestore
+% ORDRING...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 592 36 moveto
+502 36 lineto
+502 0 lineto
+592 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 592 36 moveto
+502 36 lineto
+502 0 lineto
+592 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+509 13 moveto
+(ORDRING...)
+[10.08 9.36 10.08 9.36 4.56 9.84 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->ORDRING...
+newpath 397 72 moveto
+426 62 463 49 493 38 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 494 41 moveto
+502 34 lineto
+491 35 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 494 41 moveto
+502 34 lineto
+491 35 lineto
+closepath
+stroke
+end grestore
+% RADCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 692 36 moveto
+610 36 lineto
+610 0 lineto
+692 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 692 36 moveto
+610 36 lineto
+610 0 lineto
+692 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+617 13 moveto
+(RADCAT...)
+[9.36 10.08 10.08 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RealClosedField()->RADCAT...
+newpath 406 80 moveto
+456 70 528 55 600 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 601 39 moveto
+610 33 lineto
+599 33 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 601 39 moveto
+610 33 lineto
+599 33 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102realrootcharacterizationcategory.ps b/books/ps/v102realrootcharacterizationcategory.ps
new file mode 100644
index 0000000..1fe89c5
--- /dev/null
+++ b/books/ps/v102realrootcharacterizationcategory.ps
@@ -0,0 +1,494 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 616 368
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 616 368
+%%PageOrientation: Portrait
+gsave
+36 36 580 332 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+578 330 lineto
+578 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+578 330 lineto
+578 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 572 324 moveto
+0 324 lineto
+0 288 lineto
+572 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 572 324 moveto
+0 324 lineto
+0 288 lineto
+572 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 301 moveto
+(RealRootCharacterizationCategory\(a:Join\(OrderedRing,Field\),b:UnivariatePolynomialCategory\(a\)\))
+[9.12 6.24 6.24 3.84 8.88 6.96 6.72 3.84 9.36 6.96 6.24 4.8 6.24 6.24 3.84 6.24 5.04 3.84 6.24 6.24 3.84 3.84 6.96 6.96 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 5.52 6.96 3.84 6.96 4.56 10.08 4.56 6.96 6.24 4.8 6.24 6.96 9.36 3.84 6.96 6.96 3.6 7.44 3.84 6.24 3.84 6.96 4.56 3.6 6.96 3.84 9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.44 6.96 3.6 6.96 6.96 6.96 10.8 3.84 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 333 252 moveto
+239 252 lineto
+239 216 lineto
+333 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 333 252 moveto
+239 252 lineto
+239 216 lineto
+333 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+246 229 moveto
+(SetCategory\(\))
+[7.68 6 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% RealRootCharacterizationCategory(a:Join(OrderedRing,Field),b:UnivariatePolynomialCategory(a))->SetCategory()
+newpath 286 288 moveto
+286 280 286 271 286 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 290 262 moveto
+286 252 lineto
+283 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 290 262 moveto
+286 252 lineto
+283 262 lineto
+closepath
+stroke
+end grestore
+% BasicType()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 265 108 moveto
+181 108 lineto
+181 72 lineto
+265 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 265 108 moveto
+181 108 lineto
+181 72 lineto
+265 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+188 85 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 274 216 moveto
+267 206 259 192 254 180 curveto
+245 160 236 136 231 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 234 117 moveto
+228 108 lineto
+228 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 234 117 moveto
+228 108 lineto
+228 119 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(OutputForm)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 427 180 moveto
+263 180 lineto
+263 144 lineto
+427 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 427 180 moveto
+263 180 lineto
+263 144 lineto
+427 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+271 157 moveto
+(CoercibleTo\(OutputForm\))
+[9.36 6.96 6.24 4.8 6.24 3.84 6.96 3.84 6.24 7.44 6.96 4.56 10.08 6.96 3.84 6.96 6.96 3.84 7.44 6.96 5.04 10.8 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->CoercibleTo(OutputForm)
+newpath 301 216 moveto
+308 207 316 197 324 188 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 327 190 moveto
+330 180 lineto
+321 186 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 327 190 moveto
+330 180 lineto
+321 186 lineto
+closepath
+stroke
+end grestore
+% Category
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 320 36 moveto
+252 36 lineto
+252 0 lineto
+320 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 320 36 moveto
+252 36 lineto
+252 0 lineto
+320 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+260 13 moveto
+(Category)
+[9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+xshow
+end grestore
+end grestore
+% BasicType()->Category
+newpath 239 72 moveto
+247 63 256 53 263 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 266 46 moveto
+270 36 lineto
+261 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 266 46 moveto
+270 36 lineto
+261 41 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 415 108 moveto
+283 108 lineto
+283 72 lineto
+415 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 415 108 moveto
+283 108 lineto
+283 72 lineto
+415 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+291 85 moveto
+(CoercibleTo\(a:Type\))
+[9.36 6.96 6.24 4.8 6.24 3.84 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% CoercibleTo(OutputForm)->CoercibleTo(a:Type)
+newpath 346 144 moveto
+347 136 347 127 347 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 350 118 moveto
+348 108 lineto
+344 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 350 118 moveto
+348 108 lineto
+344 118 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 333 72 moveto
+325 63 316 53 309 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 311 41 moveto
+302 36 lineto
+306 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 311 41 moveto
+302 36 lineto
+306 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102squarefreenormalizedtriangularsetcategory.ps b/books/ps/v102squarefreenormalizedtriangularsetcategory.ps
new file mode 100644
index 0000000..1284821
--- /dev/null
+++ b/books/ps/v102squarefreenormalizedtriangularsetcategory.ps
@@ -0,0 +1,335 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 872 152
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 872 152
+%%PageOrientation: Portrait
+gsave
+36 36 836 116 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+834 114 lineto
+834 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 114 lineto
+834 114 lineto
+834 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 828 108 moveto
+0 108 lineto
+0 72 lineto
+828 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 828 108 moveto
+0 108 lineto
+0 72 lineto
+828 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 85 moveto
+(SquareFreeNormalizedTriangularSetCategory\(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory\(a,b,c\)\))
+[7.68 6.72 6.96 6.24 4.8 6.24 7.44 4.8 6.24 6.24 9.84 6.96 5.04 10.8 6.24 3.84 3.84 6.24 6.24 6.96 7.92 5.04 3.84 6.24 6.96 6.96 6.96 3.84 6.24 4.8 7.68 6 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 10.08 6.24 6.96 10.08 6.96 10.8 6.24 3.84 6.96 3.6 6.96 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 7.68 6.96 6.96 3.6 6.24 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 7.68 6 3.84 3.6 6.96 3.84 9.12 6.24 6.24 6.96 4.8 5.52 3.84 6.48 6.24 7.44 6.96 3.6 6.96 6.96 6.96 10.8 3.84 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.6 6.96 3.6 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SFRTCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 407 36 moveto
+321 36 lineto
+321 0 lineto
+407 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 407 36 moveto
+321 36 lineto
+321 0 lineto
+407 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+329 13 moveto
+(SFRTCAT...)
+[7.68 7.68 8.88 8.64 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))->SFRTCAT...
+newpath 401 72 moveto
+396 64 389 54 383 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 386 42 moveto
+377 36 lineto
+380 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 386 42 moveto
+377 36 lineto
+380 46 lineto
+closepath
+stroke
+end grestore
+% NTSCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 505 36 moveto
+425 36 lineto
+425 0 lineto
+505 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 505 36 moveto
+425 36 lineto
+425 0 lineto
+505 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+432 13 moveto
+(NTSCAT...)
+[10.08 8.4 7.68 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SquareFreeNormalizedTriangularSetCategory(a:GcdDomain,b:OrderedAbelianMonoidSup,c:OrderedSet,d:RecursivePolynomialCategory(a,b,c))->NTSCAT...
+newpath 427 72 moveto
+433 64 440 54 446 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 449 46 moveto
+452 36 lineto
+443 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 449 46 moveto
+452 36 lineto
+443 42 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102univariatepuiseuxseriesconstructorcategory.ps b/books/ps/v102univariatepuiseuxseriesconstructorcategory.ps
new file mode 100644
index 0000000..446d32b
--- /dev/null
+++ b/books/ps/v102univariatepuiseuxseriesconstructorcategory.ps
@@ -0,0 +1,708 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 748 512
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 748 512
+%%PageOrientation: Portrait
+gsave
+36 36 712 476 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+710 474 lineto
+710 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+710 474 lineto
+710 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))
+[ /Rect [ 159 432 695 468 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=UPXSCCA) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 695 468 moveto
+159 468 lineto
+159 432 lineto
+695 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 695 468 moveto
+159 468 lineto
+159 432 lineto
+695 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+166 445 moveto
+(UnivariatePuiseuxSeriesConstructorCategory\(a:Ring,b:UnivariateLaurentSeriesCategory\(a\)\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.68 6.96 3.84 5.52 6.24 6.96 6.96 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.96 6.96 5.28 3.84 5.04 6.96 6.24 3.84 6.96 4.8 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 8.64 6.24 6.96 4.8 6.24 6.96 3.84 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% RETRACT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 378 396 moveto
+288 396 lineto
+288 360 lineto
+378 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 378 396 moveto
+288 396 lineto
+288 360 lineto
+378 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+296 373 moveto
+(RETRACT...)
+[9.36 8.64 8.64 9.36 9.36 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))->RETRACT...
+newpath 403 432 moveto
+392 423 377 412 364 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 366 399 moveto
+356 396 lineto
+362 405 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 366 399 moveto
+356 396 lineto
+362 405 lineto
+closepath
+stroke
+end grestore
+% UnivariatePuiseuxSeriesCategory(a:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 648 396 moveto
+396 396 lineto
+396 360 lineto
+648 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 648 396 moveto
+396 396 lineto
+396 360 lineto
+648 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+403 373 moveto
+(UnivariatePuiseuxSeriesCategory\(a:Ring\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.68 6.96 3.84 5.52 6.24 6.96 6.96 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesConstructorCategory(a:Ring,b:UnivariateLaurentSeriesCategory(a))->UnivariatePuiseuxSeriesCategory(a:Ring)
+newpath 451 432 moveto
+462 423 477 412 490 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 492 405 moveto
+498 396 lineto
+488 399 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 492 405 moveto
+498 396 lineto
+488 399 lineto
+closepath
+stroke
+end grestore
+% UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 410 324 moveto
+68 324 lineto
+68 288 lineto
+410 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 410 324 moveto
+68 324 lineto
+68 288 lineto
+410 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+76 301 moveto
+(UnivariatePowerSeriesCategory\(a:Ring,Fraction\(Integer\)\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.44 6.48 9.6 6.24 4.8 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 7.44 4.8 6.24 6.24 3.84 3.84 6.96 6.96 4.56 4.56 6.96 3.84 6.24 6.72 6.24 4.8 4.56 4.56]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesCategory(a:Ring)->UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))
+newpath 451 360 moveto
+411 350 361 337 320 326 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 320 323 moveto
+310 324 lineto
+319 329 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 320 323 moveto
+310 324 lineto
+319 329 lineto
+closepath
+stroke
+end grestore
+% TRANFUN...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 520 324 moveto
+428 324 lineto
+428 288 lineto
+520 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 520 324 moveto
+428 324 lineto
+428 288 lineto
+520 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+435 301 moveto
+(TRANFUN...)
+[8.64 9.36 10.08 10.08 7.68 10.08 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesCategory(a:Ring)->TRANFUN...
+newpath 510 360 moveto
+505 352 498 342 492 332 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 495 330 moveto
+486 324 lineto
+489 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 495 330 moveto
+486 324 lineto
+489 334 lineto
+closepath
+stroke
+end grestore
+% FIELD...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 604 324 moveto
+538 324 lineto
+538 288 lineto
+604 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 604 324 moveto
+538 324 lineto
+538 288 lineto
+604 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+545 301 moveto
+(FIELD...)
+[7.68 4.56 8.64 8.64 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesCategory(a:Ring)->FIELD...
+newpath 534 360 moveto
+540 352 547 342 553 332 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 556 334 moveto
+559 324 lineto
+550 330 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 556 334 moveto
+559 324 lineto
+550 330 lineto
+closepath
+stroke
+end grestore
+% RADCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 704 324 moveto
+622 324 lineto
+622 288 lineto
+704 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 704 324 moveto
+622 324 lineto
+622 288 lineto
+704 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+629 301 moveto
+(RADCAT...)
+[9.36 10.08 10.08 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% UnivariatePuiseuxSeriesCategory(a:Ring)->RADCAT...
+newpath 558 360 moveto
+576 350 599 339 619 329 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 621 332 moveto
+628 324 lineto
+618 326 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 621 332 moveto
+628 324 lineto
+618 326 lineto
+closepath
+stroke
+end grestore
+% UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 435 252 moveto
+43 252 lineto
+43 216 lineto
+435 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 435 252 moveto
+43 252 lineto
+43 216 lineto
+435 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+51 229 moveto
+(UnivariatePowerSeriesCategory\(a:Ring,b:OrderedAbelianMonoid\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.44 6.48 9.6 6.24 4.8 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariatePowerSeriesCategory(a:Ring,Fraction(Integer))->UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)
+newpath 239 288 moveto
+239 280 239 271 239 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 243 262 moveto
+239 252 lineto
+236 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 243 262 moveto
+239 252 lineto
+236 262 lineto
+closepath
+stroke
+end grestore
+% PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 478 180 moveto
+0 180 lineto
+0 144 lineto
+478 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 478 180 moveto
+0 180 lineto
+0 144 lineto
+478 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 157 moveto
+(PowerSeriesCategory\(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet\))
+[7.44 6.48 9.6 6.24 4.8 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 3.6 6.24 3.84 7.68 3.84 6.96 6.96 3.84 6 3.84 6.96 6.96 10.08 5.52 10.08 4.56 6.96 6.24 4.8 6.24 6.96 7.68 6 3.84 4.56]
+xshow
+end grestore
+end grestore
+% UnivariatePowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid)->PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)
+newpath 239 216 moveto
+239 208 239 199 239 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 243 190 moveto
+239 180 lineto
+236 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 243 190 moveto
+239 180 lineto
+236 190 lineto
+closepath
+stroke
+end grestore
+% PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 444 108 moveto
+34 108 lineto
+34 72 lineto
+444 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 444 108 moveto
+34 108 lineto
+34 72 lineto
+444 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+42 85 moveto
+(PowerSeriesCategory\(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet\))
+[7.44 6.48 9.6 6.24 4.8 7.68 6.24 5.04 3.84 6.24 5.52 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 3.6 6.24 3.84 10.08 4.56 6.96 6.24 4.8 6.24 6.96 7.68 6 3.84 4.56]
+xshow
+end grestore
+end grestore
+% PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:SingletonAsOrderedSet)->PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)
+newpath 239 144 moveto
+239 136 239 127 239 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 243 118 moveto
+239 108 lineto
+236 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 243 118 moveto
+239 108 lineto
+236 118 lineto
+closepath
+stroke
+end grestore
+% AMR...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 269 36 moveto
+209 36 lineto
+209 0 lineto
+269 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 269 36 moveto
+209 36 lineto
+209 0 lineto
+269 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+217 13 moveto
+(AMR...)
+[10.08 12.48 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% PowerSeriesCategory(a:Ring,b:OrderedAbelianMonoid,c:OrderedSet)->AMR...
+newpath 239 72 moveto
+239 64 239 55 239 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 243 46 moveto
+239 36 lineto
+236 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 243 46 moveto
+239 36 lineto
+236 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102univariateskewpolynomialcategory.ps b/books/ps/v102univariateskewpolynomialcategory.ps
new file mode 100644
index 0000000..02fe2bb
--- /dev/null
+++ b/books/ps/v102univariateskewpolynomialcategory.ps
@@ -0,0 +1,1152 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 724 440
+%%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
+	dup 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 aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	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
+%%Page: 1 1
+%%PageBoundingBox: 36 36 724 440
+%%PageOrientation: Portrait
+gsave
+36 36 688 404 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+686 402 lineto
+686 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+686 402 lineto
+686 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% UnivariateSkewPolynomialCategory(R:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 468 396 moveto
+198 396 lineto
+198 360 lineto
+468 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 468 396 moveto
+198 396 lineto
+198 360 lineto
+468 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+205 373 moveto
+(UnivariateSkewPolynomialCategory\(R:Ring\))
+[9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.68 6.72 5.76 10.08 7.44 6.96 3.6 6.96 6.96 6.96 10.8 3.84 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 9.36 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% BiModule(a:Ring,b:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 414 324 moveto
+252 324 lineto
+252 288 lineto
+414 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 414 324 moveto
+252 324 lineto
+252 288 lineto
+414 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+260 301 moveto
+(BiModule\(a:Ring,b:Ring\))
+[9.36 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->BiModule(a:Ring,b:Ring)
+newpath 333 360 moveto
+333 352 333 343 333 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 337 334 moveto
+333 324 lineto
+330 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 337 334 moveto
+333 324 lineto
+330 334 lineto
+closepath
+stroke
+end grestore
+% FullyRetractableTo(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 228 324 moveto
+58 324 lineto
+58 288 lineto
+228 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 228 324 moveto
+58 324 lineto
+58 288 lineto
+228 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+66 301 moveto
+(FullyRetractableTo\(a:Ring\))
+[7.44 6.96 3.84 3.6 6.96 9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->FullyRetractableTo(a:Ring)
+newpath 285 360 moveto
+259 350 227 338 199 328 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 201 325 moveto
+190 324 lineto
+198 331 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 201 325 moveto
+190 324 lineto
+198 331 lineto
+closepath
+stroke
+end grestore
+% Ring()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 489 324 moveto
+435 324 lineto
+435 288 lineto
+489 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 489 324 moveto
+435 324 lineto
+435 288 lineto
+489 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+443 301 moveto
+(Ring\(\))
+[9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% UnivariateSkewPolynomialCategory(R:Ring)->Ring()
+newpath 366 360 moveto
+384 350 407 337 426 326 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 428 329 moveto
+435 321 lineto
+425 323 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 428 329 moveto
+435 321 lineto
+425 323 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 472 252 moveto
+342 252 lineto
+342 216 lineto
+472 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 472 252 moveto
+342 252 lineto
+342 216 lineto
+472 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+350 229 moveto
+(LeftModule\(a:Ring\))
+[8.64 6.24 4.8 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% BiModule(a:Ring,b:Ring)->LeftModule(a:Ring)
+newpath 352 288 moveto
+361 279 372 269 382 259 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 384 262 moveto
+389 252 lineto
+379 257 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 384 262 moveto
+389 252 lineto
+379 257 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Ring)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 324 252 moveto
+188 252 lineto
+188 216 lineto
+324 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 324 252 moveto
+188 252 lineto
+188 216 lineto
+324 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+195 229 moveto
+(RightModule\(a:Ring\))
+[9.36 3.84 6.96 6.96 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% BiModule(a:Ring,b:Ring)->RightModule(a:Ring)
+newpath 314 288 moveto
+304 279 293 269 283 259 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 285 256 moveto
+275 252 lineto
+280 261 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 285 256 moveto
+275 252 lineto
+280 261 lineto
+closepath
+stroke
+end grestore
+% FullyRetractableTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 170 252 moveto
+0 252 lineto
+0 216 lineto
+170 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 170 252 moveto
+0 252 lineto
+0 216 lineto
+170 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 229 moveto
+(FullyRetractableTo\(a:Type\))
+[7.44 6.96 3.84 3.6 6.96 9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% FullyRetractableTo(a:Ring)->FullyRetractableTo(a:Type)
+newpath 128 288 moveto
+121 279 113 269 105 260 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 108 258 moveto
+99 252 lineto
+102 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 108 258 moveto
+99 252 lineto
+102 262 lineto
+closepath
+stroke
+end grestore
+% Rng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 544 252 moveto
+490 252 lineto
+490 216 lineto
+544 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 544 252 moveto
+490 252 lineto
+490 216 lineto
+544 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+500 229 moveto
+(Rng\(\))
+[9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Rng()
+newpath 476 288 moveto
+482 280 490 269 497 260 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 500 262 moveto
+503 252 lineto
+494 258 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 500 262 moveto
+503 252 lineto
+494 258 lineto
+closepath
+stroke
+end grestore
+% Monoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 632 252 moveto
+562 252 lineto
+562 216 lineto
+632 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 632 252 moveto
+562 252 lineto
+562 216 lineto
+632 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+569 229 moveto
+(Monoid\(\))
+[12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Monoid()
+newpath 489 291 moveto
+507 281 533 268 554 257 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 556 260 moveto
+563 252 lineto
+553 254 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 556 260 moveto
+563 252 lineto
+553 254 lineto
+closepath
+stroke
+end grestore
+% Ring()->LeftModule(a:Ring)
+newpath 448 288 moveto
+442 280 434 269 427 260 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 430 258 moveto
+421 252 lineto
+424 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 430 258 moveto
+421 252 lineto
+424 262 lineto
+closepath
+stroke
+end grestore
+% RetractableTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 155 180 moveto
+15 180 lineto
+15 144 lineto
+155 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 155 180 moveto
+15 180 lineto
+15 144 lineto
+155 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+22 157 moveto
+(RetractableTo\(a:Type\))
+[9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% FullyRetractableTo(a:Type)->RetractableTo(a:Type)
+newpath 85 216 moveto
+85 208 85 199 85 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 89 190 moveto
+85 180 lineto
+82 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 89 190 moveto
+85 180 lineto
+82 190 lineto
+closepath
+stroke
+end grestore
+% Category
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 119 108 moveto
+51 108 lineto
+51 72 lineto
+119 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 119 108 moveto
+51 108 lineto
+51 72 lineto
+119 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+59 85 moveto
+(Category)
+[9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+xshow
+end grestore
+end grestore
+% RetractableTo(a:Type)->Category
+newpath 85 144 moveto
+85 136 85 127 85 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 89 118 moveto
+85 108 lineto
+82 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 89 118 moveto
+85 108 lineto
+82 118 lineto
+closepath
+stroke
+end grestore
+% AbelianGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 460 108 moveto
+354 108 lineto
+354 72 lineto
+460 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 460 108 moveto
+354 108 lineto
+354 72 lineto
+460 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+362 85 moveto
+(AbelianGroup\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 10.08 4.8 6.96 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Rng()->AbelianGroup()
+newpath 512 216 moveto
+507 197 496 166 479 144 curveto
+470 133 458 122 446 114 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 448 111 moveto
+438 108 lineto
+444 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 448 111 moveto
+438 108 lineto
+444 117 lineto
+closepath
+stroke
+end grestore
+% SemiGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 634 180 moveto
+544 180 lineto
+544 144 lineto
+634 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 634 180 moveto
+544 180 lineto
+544 144 lineto
+634 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+552 157 moveto
+(SemiGroup\(\))
+[7.68 6.24 10.8 3.84 10.08 4.8 6.96 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Rng()->SemiGroup()
+newpath 535 216 moveto
+544 207 554 197 564 187 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 566 190 moveto
+571 180 lineto
+561 185 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 566 190 moveto
+571 180 lineto
+561 185 lineto
+closepath
+stroke
+end grestore
+% Monoid()->SemiGroup()
+newpath 595 216 moveto
+594 208 593 199 592 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 595 190 moveto
+591 180 lineto
+589 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 595 190 moveto
+591 180 lineto
+589 190 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 470 180 moveto
+344 180 lineto
+344 144 lineto
+470 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 470 180 moveto
+344 180 lineto
+344 144 lineto
+470 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+352 157 moveto
+(LeftModule\(a:Rng\))
+[8.64 6.24 4.8 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% LeftModule(a:Ring)->LeftModule(a:Rng)
+newpath 407 216 moveto
+407 208 407 199 407 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 411 190 moveto
+407 180 lineto
+404 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 411 190 moveto
+407 180 lineto
+404 190 lineto
+closepath
+stroke
+end grestore
+% CABMON...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 402 36 moveto
+314 36 lineto
+314 0 lineto
+402 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 402 36 moveto
+314 36 lineto
+314 0 lineto
+402 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+322 13 moveto
+(CABMON...)
+[9.12 10.08 9.36 12.48 10.08 9.84 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->CABMON...
+newpath 395 72 moveto
+389 64 382 54 376 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 379 42 moveto
+370 36 lineto
+373 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 379 42 moveto
+370 36 lineto
+373 46 lineto
+closepath
+stroke
+end grestore
+% REPDB...
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 492 36 moveto
+420 36 lineto
+420 0 lineto
+492 0 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 492 36 moveto
+420 36 lineto
+420 0 lineto
+492 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+427 13 moveto
+(REPDB...)
+[9.36 8.64 7.68 10.08 9.36 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->REPDB...
+newpath 419 72 moveto
+425 64 432 54 438 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 441 46 moveto
+444 36 lineto
+435 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 441 46 moveto
+444 36 lineto
+435 42 lineto
+closepath
+stroke
+end grestore
+% SETCAT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 592 108 moveto
+514 108 lineto
+514 72 lineto
+592 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 592 108 moveto
+514 108 lineto
+514 72 lineto
+592 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+522 85 moveto
+(SETCAT...)
+[7.68 8.64 8.64 9.12 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SemiGroup()->SETCAT...
+newpath 580 144 moveto
+576 136 571 126 566 117 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 569 116 moveto
+562 108 lineto
+563 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 569 116 moveto
+562 108 lineto
+563 119 lineto
+closepath
+stroke
+end grestore
+% REPSQ...
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 680 108 moveto
+610 108 lineto
+610 72 lineto
+680 72 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 680 108 moveto
+610 108 lineto
+610 72 lineto
+680 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+617 85 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% SemiGroup()->REPSQ...
+newpath 603 144 moveto
+610 136 618 125 625 116 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 628 118 moveto
+631 108 lineto
+622 114 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 628 118 moveto
+631 108 lineto
+622 114 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 324 180 moveto
+190 180 lineto
+190 144 lineto
+324 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 324 180 moveto
+190 180 lineto
+190 144 lineto
+324 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+198 157 moveto
+(RightModule\(a:Rng\))
+[9.36 3.84 6.96 6.96 3.84 12.48 6.96 6.96 6.96 3.84 6.24 4.56 6.24 3.84 9.36 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% RightModule(a:Ring)->RightModule(a:Rng)
+newpath 256 216 moveto
+257 208 257 199 257 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 261 190 moveto
+257 180 lineto
+254 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 261 190 moveto
+257 180 lineto
+254 190 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->AbelianGroup()
+newpath 295 144 moveto
+315 134 340 123 361 112 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 362 115 moveto
+370 108 lineto
+359 109 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 362 115 moveto
+370 108 lineto
+359 109 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->AbelianGroup()
+newpath 407 144 moveto
+407 136 407 127 407 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 411 118 moveto
+407 108 lineto
+404 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 411 118 moveto
+407 108 lineto
+404 118 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/changelog b/changelog
index 099ffff..e652236 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,30 @@
+20081112 tpd books/bookvol10.2 add categories
+20081112 tpd books/ps/v102quaternioncategory.ps added
+20081112 tpd src/algebra/quat.spad move QUATCAT to bookvol10.2
+20081112 tpd src/algebra/ore.spad move category to bookvol10.2
+20081112 tpd src/algebra/lodo.spad move category to bookvol10.2
+20081112 tpd src/algebra/perm.spad move category to bookvol10.2
+20081112 tpd src/algebra/si.spad move INS to bookvol10.2
+20081112 tpd books/ps/v102univariatepuiseuxseriesconstructorcategory.ps added
+20081112 tpd src/input/r20bugs.input fix S17 result for complexRoots
+20081112 tpd books/ps/v102partialtranscendentalfunctions.ps added
+20081112 tpd src/algebra/Makefile remove ptranfn.spad
+20081112 tpd books/ps/v102univariatepuiseuxseriesconstructorcategory.ps added
+20081112 tpd src/algebra/puiseux.spad move category to bookvol10.2
+20081112 tpd books/ps/v102partialtranscendentalfunctions.ps added
+20081112 tpd src/algebra/ptranfn.spad merged with bookvol10.2
+20081112 tpd books/ps/v102squarefreenormalizedtriangularsetcategory.ps added
+20081112 tpd src/algebra/nsregset.spad add SNTSCAT to bookvol10.2
+20081112 tpd books/ps/v102eltab.ps corrected
+20081112 tpd books/ps/v102linearordinarydifferentialoperatorcategory.ps added
+20081112 tpd src/algebra/lodo.spad add LODOCAT to bookvol10.2
+20081112 tpd books/ps/v102univariateskewpolynomialcategory.ps added
+20081112 tpd src/algebra/ore.spad move OREPCAT to bookvol10.2
+20081112 tpd books/ps/v102complexcategory.ps added
+20081112 tpd src/algebra/gaussian.spad move categories to bookvol10.2
+20081112 tpd books/ps/v102realrootcharacterizationcategory.ps added
+20081112 tpd books/ps/v102realclosedfield.ps added
+20081112 tpd src/algebra/reclos.spad move categories to bookvol10.2
 20081110 tpd books/bookvol10.2 add categories
 20081110 tpd books/ps/v102normalizedtriangularsetcategory.ps added
 20081110 tpd src/algebra/nregset.spad move NTSCAT to bookvol10.2
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 5ff5e10..e537f92 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -174,7 +174,6 @@ LAYER0COPY=\
 \begin{verbatim}
 dhmatrix.spad.pamphlet (DHMATRIX)
 print.spad.pamphlet   (PRINT)
-ptranfn.spad.pamphlet (PTRANFN)
 system.spad.pamphlet  (MSYSCMD)
 \end{verbatim}
 
@@ -1269,8 +1268,7 @@ SPADFILES= \
  ${OUTSRC}/polset.spad ${OUTSRC}/poltopol.spad ${OUTSRC}/polycat.spad \
  ${OUTSRC}/poly.spad ${OUTSRC}/primelt.spad ${OUTSRC}/print.spad \
  ${OUTSRC}/product.spad ${OUTSRC}/prs.spad ${OUTSRC}/prtition.spad \
- ${OUTSRC}/pseudolin.spad ${OUTSRC}/ptranfn.spad \
- ${OUTSRC}/puiseux.spad \
+ ${OUTSRC}/pseudolin.spad ${OUTSRC}/puiseux.spad \
  ${OUTSRC}/qalgset.spad ${OUTSRC}/quat.spad \
  ${OUTSRC}/radeigen.spad ${OUTSRC}/radix.spad ${OUTSRC}/random.spad \
  ${OUTSRC}/ratfact.spad ${OUTSRC}/rdeef.spad ${OUTSRC}/rderf.spad \
@@ -1430,8 +1428,7 @@ DOCFILES= \
  ${DOC}/polset.spad.dvi ${DOC}/poltopol.spad.dvi ${DOC}/polycat.spad.dvi \
  ${DOC}/poly.spad.dvi ${DOC}/primelt.spad.dvi ${DOC}/print.spad.dvi \
  ${DOC}/product.spad.dvi ${DOC}/prs.spad.dvi ${DOC}/prtition.spad.dvi \
- ${DOC}/pseudolin.spad.dvi ${DOC}/ptranfn.spad.dvi \
- ${DOC}/puiseux.spad.dvi \
+ ${DOC}/pseudolin.spad.dvi ${DOC}/puiseux.spad.dvi \
  ${DOC}/qalgset.spad.dvi ${DOC}/quat.spad.dvi \
  ${DOC}/radeigen.spad.dvi ${DOC}/radix.spad.dvi ${DOC}/random.spad.dvi \
  ${DOC}/ratfact.spad.dvi ${DOC}/rdeef.spad.dvi ${DOC}/rderf.spad.dvi \
diff --git a/src/algebra/gaussian.spad.pamphlet b/src/algebra/gaussian.spad.pamphlet
index d74aecc..c6e05d3 100644
--- a/src/algebra/gaussian.spad.pamphlet
+++ b/src/algebra/gaussian.spad.pamphlet
@@ -9,442 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category COMPCAT ComplexCategory}
-<<category COMPCAT ComplexCategory>>=
-)abbrev category COMPCAT ComplexCategory
-++ Author:
-++ Date Created:
-++ Date Last Updated: 18 March 1994
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: complex, gaussian
-++ References:
-++ Description:
-++ This category represents the extension of a ring by a square
-++ root of -1.
-ComplexCategory(R:CommutativeRing): Category ==
-  Join(MonogenicAlgebra(R, SparseUnivariatePolynomial R), FullyRetractableTo R,
-   DifferentialExtension R, FullyEvalableOver R, FullyPatternMatchable(R),
-    Patternable(R), FullyLinearlyExplicitRingOver R, CommutativeRing) with
-     complex                       ++ indicates that % has sqrt(-1)
-     imaginary:   () -> %          ++ imaginary() = sqrt(-1) = %i.
-     conjugate:   % -> %           ++ conjugate(x + %i y) returns x - %i y.
-     complex  :   (R, R) -> %      ++ complex(x,y) constructs x + %i*y.
-     imag     :   % -> R           ++ imag(x) returns imaginary part of x.
-     real     :   % -> R           ++ real(x) returns real part of x.
-     norm     :   % -> R           ++ norm(x) returns x * conjugate(x)
-     if R has OrderedSet then OrderedSet
-     if R has IntegralDomain then
-       IntegralDomain
-       _exquo : (%,R) -> Union(%,"failed")
-         ++ exquo(x, r) returns the exact quotient of x by r, or
-         ++ "failed" if r does not divide x exactly.
-     if R has EuclideanDomain then EuclideanDomain
-     if R has multiplicativeValuation then multiplicativeValuation
-     if R has additiveValuation then additiveValuation
-     if R has Field then        -- this is a lie; we must know that
-       Field                    -- x**2+1 is irreducible in R
-     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
-     if R has CharacteristicZero then CharacteristicZero
-     if R has CharacteristicNonZero then CharacteristicNonZero
-     if R has RealConstant then
-       ConvertibleTo Complex DoubleFloat
-       ConvertibleTo Complex Float
-     if R has RealNumberSystem then
-       abs: % -> %
-         ++ abs(x) returns the absolute value of x = sqrt(norm(x)).
-     if R has TranscendentalFunctionCategory then
-       TranscendentalFunctionCategory
-       argument: % -> R  ++ argument(x) returns the angle made by (0,1) and (0,x).
-       if R has RadicalCategory then RadicalCategory
-       if R has RealNumberSystem then
-         polarCoordinates: % -> Record(r:R, phi:R)
-           ++ polarCoordinates(x) returns (r, phi) such that x = r * exp(%i * phi).
-     if R has IntegerNumberSystem then
-       rational?    : % -> Boolean
-         ++ rational?(x) tests if x is a rational number.
-       rational     : % -> Fraction Integer
-         ++ rational(x) returns x as a rational number.
-         ++ Error: if x is not a rational number.
-       rationalIfCan: % -> Union(Fraction Integer, "failed")
-         ++ rationalIfCan(x) returns x as a rational number, or
-         ++ "failed" if x is not a rational number.
-     if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
-        PolynomialFactorizationExplicit
- add
-       import MatrixCategoryFunctions2(%, Vector %, Vector %, Matrix %,
-                                       R, Vector R, Vector R, Matrix R)
-       SUP ==> SparseUnivariatePolynomial
-       characteristicPolynomial x ==
-          v := monomial(1,1)$SUP(R)
-          v**2 - trace(x)*v**1 + norm(x)*v**0
-       if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
-          SupR ==> SparseUnivariatePolynomial R
-          Sup ==> SparseUnivariatePolynomial %
-          import FactoredFunctionUtilities Sup
-          import UnivariatePolynomialCategoryFunctions2(R,SupR,%,Sup)
-          import UnivariatePolynomialCategoryFunctions2(%,Sup,R,SupR)
-          pp,qq:Sup
-          if R has IntegerNumberSystem then
-             myNextPrime: (%,NonNegativeInteger) -> %
-             myNextPrime(x,n ) == -- prime is actually in R, and = 3(mod 4)
-                xr:=real(x)-4::R
-                while not prime? xr repeat
-                   xr:=xr-4::R
-                complex(xr,0)
-             --!TT:=InnerModularGcd(%,Sup,32719 :: %,myNextPrime)
-             --!gcdPolynomial(pp,qq) == modularGcd(pp,qq)$TT
-             solveLinearPolynomialEquation(lp:List Sup,p:Sup) ==
-               solveLinearPolynomialEquation(lp,p)$ComplexIntegerSolveLinearPolynomialEquation(R,%)
-          normPolynomial: Sup -> SupR
-          normPolynomial pp ==
-              map(retract(#1@%)::R,pp * map(conjugate,pp))
-          factorPolynomial pp ==
-              refine(squareFree pp,factorSquareFreePolynomial)
-          factorSquareFreePolynomial pp ==
-              pnorm:=normPolynomial pp
-              k:R:=0
-              while degree gcd(pnorm,differentiate pnorm)>0 repeat
-                 k:=k+1
-                 pnorm:=normPolynomial
-                          elt(pp,monomial(1,1)-monomial(complex(0,k),0))
-              fR:=factorSquareFreePolynomial pnorm
-              numberOfFactors fR = 1 =>
-                  makeFR(1,[["irred",pp,1]])
-              lF:List Record(flg:Union("nil", "sqfr", "irred", "prime"),
-                             fctr:Sup, xpnt:Integer):=[]
-              for u in factorList fR repeat
-                  p1:=map((#1@R)::%,u.fctr)
-                  if not zero? k then
-                     p1:=elt(p1,monomial(1,1)+monomial(complex(0,k),0))
-                  p2:=gcd(p1,pp)
-                  lF:=cons(["irred",p2,1],lF)
-                  pp:=(pp exquo p2)::Sup
-              makeFR(pp,lF)
-       rank()           == 2
-       discriminant()   == -4 :: R
-       norm x           == real(x)**2 + imag(x)**2
-       trace x          == 2 * real x
-       imaginary()      == complex(0, 1)
-       conjugate x      == complex(real x, - imag x)
-       characteristic() == characteristic()$R
-       map(fn, x)       == complex(fn real x, fn imag x)
-       x = y            == real(x) = real(y) and imag(x) = imag(y)
-       x + y            == complex(real x + real y, imag x + imag y)
-       - x              == complex(- real x, - imag x)
-       r:R * x:%        == complex(r * real x, r * imag x)
-       coordinates(x:%) == [real x, imag x]
-       n:Integer * x:%  == complex(n * real x, n * imag x)
-       differentiate(x:%, d:R -> R) == complex(d real x, d imag x)
-
-       definingPolynomial() ==
-         monomial(1,2)$(SUP R) + monomial(1,0)$(SUP R)
-
-       reduce(pol:SUP R) ==
-         part:= (monicDivide(pol,definingPolynomial())).remainder
-         complex(coefficient(part,0),coefficient(part,1))
-
-       lift(x) == monomial(real x,0)$(SUP R)+monomial(imag x,1)$(SUP R)
-
-       minimalPolynomial x ==
-         zero? imag x =>
-           monomial(1, 1)$(SUP R) - monomial(real x, 0)$(SUP R)
-         monomial(1, 2)$(SUP R) - monomial(trace x, 1)$(SUP R)
-           + monomial(norm x, 0)$(SUP R)
-
-       coordinates(x:%, v:Vector %):Vector(R) ==
-         ra := real(a := v(minIndex v))
-         rb := real(b := v(maxIndex v))
-         (#v ^= 2) or
-           ((d := recip(ra * (ib := imag b) - (ia := imag a) * rb))
-             case "failed") =>error "coordinates: vector is not a basis"
-         rx := real x
-         ix := imag x
-         [d::R * (rx * ib - ix * rb), d::R * (ra * ix - ia * rx)]
-
-       coerce(x:%):OutputForm ==
-         re := (r := real x)::OutputForm
-         ie := (i := imag x)::OutputForm
-         zero? i => re
-         outi := "%i"::Symbol::OutputForm
-         ip :=
---           one? i => outi
-           (i = 1) => outi
---           one?(-i) => -outi
-           ((-i) = 1) => -outi
-           ie * outi
-         zero? r => ip
-         re + ip
-
-       retract(x:%):R ==
-         not zero?(imag x) =>
-           error "Imaginary part is nonzero. Cannot retract."
-         real x
-
-       retractIfCan(x:%):Union(R, "failed") ==
-         not zero?(imag x) => "failed"
-         real x
-
-       x:% * y:% ==
-         complex(real x * real y - imag x * imag y,
-                  imag x * real y + imag y * real x)
-
-       reducedSystem(m:Matrix %):Matrix R ==
-         vertConcat(map(real, m), map(imag, m))
-
-       reducedSystem(m:Matrix %, v:Vector %):
-        Record(mat:Matrix R, vec:Vector R) ==
-         rh := reducedSystem(v::Matrix %)@Matrix(R)
-         [reducedSystem(m)@Matrix(R), column(rh, minColIndex rh)]
-
-       if R has RealNumberSystem then
-         abs(x:%):%        == (sqrt norm x)::%
-
-       if R has RealConstant then
-         convert(x:%):Complex(DoubleFloat) ==
-          complex(convert(real x)@DoubleFloat,convert(imag x)@DoubleFloat)
-
-         convert(x:%):Complex(Float) ==
-           complex(convert(real x)@Float, convert(imag x)@Float)
-
-       if R has ConvertibleTo InputForm then
-         convert(x:%):InputForm ==
-           convert([convert("complex"::Symbol), convert real x,
-                    convert imag x]$List(InputForm))@InputForm
-
-       if R has ConvertibleTo Pattern Integer then
-         convert(x:%):Pattern Integer ==
-            convert(x)$ComplexPattern(Integer, R, %)
-       if R has ConvertibleTo Pattern Float then
-         convert(x:%):Pattern Float ==
-            convert(x)$ComplexPattern(Float, R, %)
-
-       if R has PatternMatchable Integer then
-         patternMatch(x:%, p:Pattern Integer,
-          l:PatternMatchResult(Integer, %)) ==
-           patternMatch(x, p, l)$ComplexPatternMatch(Integer, R, %)
-
-       if R has PatternMatchable Float then
-         patternMatch(x:%, p:Pattern Float,
-          l:PatternMatchResult(Float, %)) ==
-           patternMatch(x, p, l)$ComplexPatternMatch(Float, R, %)
-
-
-       if R has OrderedSet then
-         x < y ==
-           real x = real y => imag x < imag y
-           real x < real y
-
-       if R has IntegerNumberSystem then
-         rational? x == zero? imag x
-
-         rational x ==
-           zero? imag x => rational real x
-           error "Not a rational number"
-
-         rationalIfCan x ==
-           zero? imag x => rational real x
-           "failed"
-
-       if R has Field then
-         inv x ==
-           zero? imag x => (inv real x)::%
-           r := norm x
-           complex(real(x) / r, - imag(x) / r)
-
-       if R has IntegralDomain then
-         _exquo(x:%, r:R) ==
---           one? r => x
-           (r = 1) => x
-           (r1 := real(x) exquo r) case "failed" => "failed"
-           (r2 := imag(x) exquo r) case "failed" => "failed"
-           complex(r1, r2)
-
-         _exquo(x:%, y:%) ==
-           zero? imag y => x exquo real y
-           x * conjugate(y) exquo norm(y)
-
-         recip(x:%) == 1 exquo x
-
-         if R has OrderedRing then
-           unitNormal x ==
-             zero? x => [1,x,1]
-             (u := recip x) case % => [x, 1, u]
-             zero? real x =>
-               c := unitNormal imag x
-               [complex(0, c.unit), (c.associate * imag x)::%,
-                                              complex(0, - c.associate)]
-             c := unitNormal real x
-             x := c.associate * x
-             imag x < 0 =>
-               x := complex(- imag x, real x)
-               [- c.unit * imaginary(), x, c.associate * imaginary()]
-             [c.unit ::%, x, c.associate ::%]
-         else
-           unitNormal x ==
-             zero? x => [1,x,1]
-             (u := recip x) case % => [x, 1, u]
-             zero? real x =>
-               c := unitNormal imag x
-               [complex(0, c.unit), (c.associate * imag x)::%,
-                                              complex(0, - c.associate)]
-             c := unitNormal real x
-             x := c.associate * x
-             [c.unit ::%, x, c.associate ::%]
-
-       if R has EuclideanDomain then
-          if R has additiveValuation then
-              euclideanSize x == max(euclideanSize real x,
-                                     euclideanSize imag x)
-          else
-              euclideanSize x == euclideanSize(real(x)**2 + imag(x)**2)$R
-          if R has IntegerNumberSystem then
-            x rem y ==
-              zero? imag y =>
-                yr:=real y
-                complex(symmetricRemainder(real(x), yr),
-                        symmetricRemainder(imag(x), yr))
-              divide(x, y).remainder
-            x quo y ==
-              zero? imag y =>
-                yr:= real y
-                xr:= real x
-                xi:= imag x
-                complex((xr-symmetricRemainder(xr,yr)) quo yr,
-                        (xi-symmetricRemainder(xi,yr)) quo yr)
-              divide(x, y).quotient
-
-          else
-            x rem y ==
-              zero? imag y =>
-                yr:=real y
-                complex(real(x) rem yr,imag(x) rem yr)
-              divide(x, y).remainder
-            x quo y ==
-              zero? imag y => complex(real x quo real y,imag x quo real y)
-              divide(x, y).quotient
-
-          divide(x, y) ==
-            r := norm y
-            y1 := conjugate y
-            xx := x * y1
-            x1 := real(xx) rem r
-            a  := x1
-            if x1^=0 and sizeLess?(r, 2 * x1) then
-              a := x1 - r
-              if sizeLess?(x1, a) then a := x1 + r
-            x2 := imag(xx) rem r
-            b  := x2
-            if x2^=0 and sizeLess?(r, 2 * x2) then
-              b := x2 - r
-              if sizeLess?(x2, b) then b := x2 + r
-            y1 := (complex(a, b) exquo y1)::%
-            [((x - y1) exquo y)::%, y1]
-
-       if R has TranscendentalFunctionCategory then
-         half := recip(2::R)::R
-
-         if R has RealNumberSystem then
-           atan2loc(y: R, x: R): R ==
-               pi1 := pi()$R
-               pi2 := pi1 * half
-               x = 0 => if y >= 0 then pi2 else -pi2
-
-               -- Atan in (-pi/2,pi/2]
-               theta := atan(y * recip(x)::R)
-               while theta <= -pi2 repeat theta := theta + pi1
-               while theta >   pi2 repeat theta := theta - pi1
-
-               x >= 0 => theta      -- I or IV
-
-               if y >= 0 then
-                   theta + pi1      -- II
-               else
-                   theta - pi1      -- III
-
-           argument x == atan2loc(imag x, real x)
-
-         else
-           -- Not ordered so dictate two quadrants
-           argument x ==
-             zero? real x => pi()$R * half
-             atan(imag(x) * recip(real x)::R)
-
-         pi()  == pi()$R :: %
-
-         if R is DoubleFloat then
-            stoc ==> S_-TO_-C$Lisp
-            ctos ==> C_-TO_-S$Lisp
-
-            exp   x == ctos EXP(stoc x)$Lisp
-            log   x == ctos LOG(stoc x)$Lisp
-
-            sin   x == ctos SIN(stoc x)$Lisp
-            cos   x == ctos COS(stoc x)$Lisp
-            tan   x == ctos TAN(stoc x)$Lisp
-            asin  x == ctos ASIN(stoc x)$Lisp
-            acos  x == ctos ACOS(stoc x)$Lisp
-            atan  x == ctos ATAN(stoc x)$Lisp
-
-            sinh  x == ctos SINH(stoc x)$Lisp
-            cosh  x == ctos COSH(stoc x)$Lisp
-            tanh  x == ctos TANH(stoc x)$Lisp
-            asinh x == ctos ASINH(stoc x)$Lisp
-            acosh x == ctos ACOSH(stoc x)$Lisp
-            atanh x == ctos ATANH(stoc x)$Lisp
-
-         else
-           atan x ==
-             ix := imaginary()*x
-             - imaginary() * half * (log(1 + ix) - log(1 - ix))
-
-           log x ==
-             complex(log(norm x) * half, argument x)
-
-           exp x ==
-             e := exp real x
-             complex(e * cos imag x, e * sin imag x)
-
-           cos x ==
-             e := exp(imaginary() * x)
-             half * (e + recip(e)::%)
-
-           sin x ==
-             e := exp(imaginary() * x)
-             - imaginary() * half * (e - recip(e)::%)
-
-         if R has RealNumberSystem then
-           polarCoordinates x ==
-             [sqrt norm x, (negative?(t := argument x) => t + 2 * pi(); t)]
-
-           x:% ** q:Fraction(Integer) ==
-             zero? q =>
-               zero? x => error "0 ** 0 is undefined"
-               1
-             zero? x => 0
-             rx := real x
-             zero? imag x and positive? rx => (rx ** q)::%
-             zero? imag x and denom q = 2 => complex(0, (-rx)**q)
-             ax := sqrt(norm x) ** q
-             tx := q::R * argument x
-             complex(ax * cos tx, ax * sin tx)
-
-         else if R has RadicalCategory then
-           x:% ** q:Fraction(Integer) ==
-             zero? q =>
-               zero? x => error "0 ** 0 is undefined"
-               1
-             r := real x
-             zero?(i := imag x) => (r ** q)::%
-             t := numer(q) * recip(denom(q)::R)::R * argument x
-             e:R :=
-               zero? r => i ** q
-               norm(x) ** (q / (2::Fraction(Integer)))
-             complex(e * cos t, e * sin t)
-
-@
 \section{package COMPLPAT ComplexPattern}
 <<package COMPLPAT ComplexPattern>>=
 )abbrev package COMPLPAT ComplexPattern
@@ -1093,7 +657,6 @@ ComplexIntegerSolveLinearPolynomialEquation(R,CR): C == T
 <<*>>=
 <<license>>
 
-<<category COMPCAT ComplexCategory>>
 <<package COMPLPAT ComplexPattern>>
 <<package CPMATCH ComplexPatternMatch>>
 <<domain COMPLEX Complex>>
diff --git a/src/algebra/lodo.spad.pamphlet b/src/algebra/lodo.spad.pamphlet
index 0e499d1..fd3136a 100644
--- a/src/algebra/lodo.spad.pamphlet
+++ b/src/algebra/lodo.spad.pamphlet
@@ -9,64 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category LODOCAT LinearOrdinaryDifferentialOperatorCategory}
-<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>=
-)abbrev category LODOCAT LinearOrdinaryDifferentialOperatorCategory
-++ Author: Manuel Bronstein
-++ Date Created: 9 December 1993
-++ Date Last Updated: 15 April 1994
-++ Keywords: differential operator
-++ Description:
-++   \spad{LinearOrdinaryDifferentialOperatorCategory} is the category
-++   of differential operators with coefficients in a ring A with a given
-++   derivation.
-++   Multiplication of operators corresponds to functional composition:
-++       \spad{(L1 * L2).(f) = L1 L2 f}
-LinearOrdinaryDifferentialOperatorCategory(A:Ring): Category ==
-  Join(UnivariateSkewPolynomialCategory A, Eltable(A, A)) with
-        D: () -> %
-            ++ D() provides the operator corresponding to a derivation
-            ++ in the ring \spad{A}.
-        adjoint: % -> %
-            ++ adjoint(a) returns the adjoint operator of a.
-        if A has Field then
-          symmetricProduct: (%, %) -> %
-            ++ symmetricProduct(a,b) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the products of a solution of \spad{a} by
-            ++ a solution of \spad{b}.
-          symmetricPower  : (%, NonNegativeInteger) -> %
-            ++ symmetricPower(a,n) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the products of \spad{n} solutions
-            ++ of \spad{a}.
-          symmetricSquare : % -> %
-            ++ symmetricSquare(a) computes \spad{symmetricProduct(a,a)}
-            ++ using a more efficient method.
-          directSum: (%, %) -> %
-            ++ directSum(a,b) computes an operator \spad{c} of
-            ++ minimal order such that the nullspace of \spad{c} is
-            ++ generated by all the sums of a solution of \spad{a} by
-            ++ a solution of \spad{b}.
-   add
-        m1monom: NonNegativeInteger -> %
-
-        D() == monomial(1, 1)
-
-        m1monom n ==
-          a:A := (odd? n => -1; 1)
-          monomial(a, n)
-
-        adjoint a ==
-          ans:% := 0
-          while a ^= 0 repeat
-            ans := ans + m1monom(degree a) * leadingCoefficient(a)::%
-            a   := reductum a
-          ans
-
-        if A has Field then symmetricSquare l == symmetricPower(l, 2)
-
-@
 \section{package LODOOPS LinearOrdinaryDifferentialOperatorsOps}
 <<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>=
 )abbrev package LODOOPS LinearOrdinaryDifferentialOperatorsOps
@@ -1699,7 +1641,6 @@ LinearOrdinaryDifferentialOperator2(A, M): Exports == Implementation where
 <<*>>=
 <<license>>
 
-<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>
 <<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>
 <<domain LODO LinearOrdinaryDifferentialOperator>>
 <<domain LODO1 LinearOrdinaryDifferentialOperator1>>
diff --git a/src/algebra/nsregset.spad.pamphlet b/src/algebra/nsregset.spad.pamphlet
index 13d90b2..fb5965a 100644
--- a/src/algebra/nsregset.spad.pamphlet
+++ b/src/algebra/nsregset.spad.pamphlet
@@ -9,30 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category SNTSCAT SquareFreeNormalizedTriangularSetCategory}
-<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>=
-)abbrev category SNTSCAT SquareFreeNormalizedTriangularSetCategory
-++ Author: Marc Moreno Maza
-++ Date Created: 10/07/1998
-++ Date Last Updated: 12/16/1998
-++ Basic Functions:
-++ Related Constructors:
-++ Also See: essai Graphisme
-++ AMS Classifications:
-++ Keywords: polynomial, multivariate, ordered variables set
-++ Description:
-++ The category of square-free and normalized triangular sets.
-++ Thus, up to the primitivity axiom of [1], these sets are Lazard
-++ triangular sets.\newline
-++ References :
-++  [1] D. LAZARD "A new method for solving algebraic systems of 
-++      positive dimension" Discr. App. Math. 33:147-160,1991
-SquareFreeNormalizedTriangularSetCategory(R:GcdDomain,E:OrderedAbelianMonoidSup,_
- V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
-         Category == 
-   Join(SquareFreeRegularTriangularSetCategory(R,E,V,P), NormalizedTriangularSetCategory(R,E,V,P))
-
-@
 \section{package LAZM3PK LazardSetSolvingPackage}
 <<package LAZM3PK LazardSetSolvingPackage>>=
 )abbrev package LAZM3PK LazardSetSolvingPackage
@@ -193,7 +169,6 @@ LazardSetSolvingPackage(R,E,V,P,TS,ST): Exports == Implementation where
 <<*>>=
 <<license>>
 
-<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>
 <<package LAZM3PK LazardSetSolvingPackage>>
 @
 \eject
diff --git a/src/algebra/ore.spad.pamphlet b/src/algebra/ore.spad.pamphlet
index 1c567eb..8e07b6b 100644
--- a/src/algebra/ore.spad.pamphlet
+++ b/src/algebra/ore.spad.pamphlet
@@ -9,245 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category OREPCAT UnivariateSkewPolynomialCategory}
-<<category OREPCAT UnivariateSkewPolynomialCategory>>=
-)abbrev category OREPCAT UnivariateSkewPolynomialCategory
-++ Author: Manuel Bronstein, Jean Della Dora, Stephen M. Watt
-++ Date Created: 19 October 1993
-++ Date Last Updated: 1 February 1994
-++ Description:
-++   This is the category of univariate skew polynomials over an Ore
-++   coefficient ring.
-++   The multiplication is given by \spad{x a = \sigma(a) x + \delta a}.
-++   This category is an evolution of the types
-++     MonogenicLinearOperator, OppositeMonogenicLinearOperator, and
-++     NonCommutativeOperatorDivision
-++   developped by Jean Della Dora and Stephen M. Watt.
-UnivariateSkewPolynomialCategory(R:Ring):
-  Category == Join(Ring, BiModule(R, R), FullyRetractableTo R) with
-        degree: $ -> NonNegativeInteger
-            ++ degree(l) is \spad{n} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        minimumDegree: $ -> NonNegativeInteger
-            ++ minimumDegree(l) is the smallest \spad{k} such that
-            ++ \spad{a(k) ^= 0} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        leadingCoefficient: $ -> R
-            ++ leadingCoefficient(l) is \spad{a(n)} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        reductum: $ -> $
-            ++ reductum(l) is \spad{l - monomial(a(n),n)} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        coefficient: ($, NonNegativeInteger) -> R
-            ++ coefficient(l,k) is \spad{a(k)} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        monomial: (R, NonNegativeInteger) -> $
-            ++ monomial(c,k) produces c times the k-th power of
-            ++ the generating operator, \spad{monomial(1,1)}.
-        coefficients: % -> List R
-            ++ coefficients(l) returns the list of all the nonzero
-            ++ coefficients of l.
-        apply: (%, R, R) -> R
-          ++ apply(p, c, m) returns \spad{p(m)} where the action is
-          ++ given by \spad{x m = c sigma(m) + delta(m)}.
-        if R has CommutativeRing then Algebra R
-        if R has IntegralDomain then
-          "exquo": (%, R) -> Union(%, "failed")
-            ++ exquo(l, a) returns the exact quotient of l by a, 
-            ++ returning \axiom{"failed"} if this is not possible.
-          monicLeftDivide:   (%, %) -> Record(quotient: %, remainder: %)
-            ++ monicLeftDivide(a,b) returns the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ \spad{b} must be monic.
-            ++ This process is called ``left division''.
-          monicRightDivide:   (%, %) -> Record(quotient: %, remainder: %)
-            ++ monicRightDivide(a,b) 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''.
-        if R has GcdDomain then
-          content: % -> R
-            ++ content(l) returns the gcd of all the coefficients of l.
-          primitivePart: % -> %
-            ++ primitivePart(l) returns l0 such that \spad{l = a * l0}
-            ++ for some a in R, and \spad{content(l0) = 1}.
-        if R has Field then
-          leftDivide:   (%, %) -> Record(quotient: %, remainder: %)
-            ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ This process is called ``left division''.
-          leftQuotient:  (%, %) -> %
-            ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ The value \spad{q} is returned.
-          leftRemainder:  (%, %) -> %
-            ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
-            ++ \spad{a = b*q + r} and the degree of \spad{r} is
-            ++ less than the degree of \spad{b}.
-            ++ The value \spad{r} is returned.
-          leftExactQuotient:(%, %) -> Union(%, "failed")
-            ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
-            ++  such that \spad{a = b*q}.
-          leftGcd:   (%, %) -> %
-            ++ leftGcd(a,b) computes the value \spad{g} of highest degree
-            ++ such that
-            ++    \spad{a = g*aa}
-            ++    \spad{b = g*bb}
-            ++ for some values \spad{aa} and \spad{bb}.
-            ++ The value \spad{g} is computed using left-division.
-          leftExtendedGcd:   (%, %) -> Record(coef1:%, coef2:%, generator:%)
-            ++ leftExtendedGcd(a,b) returns \spad{[c,d]} such that
-            ++ \spad{g = a * c + b * d = leftGcd(a, b)}.
-          rightLcm:   (%, %) -> %
-            ++ rightLcm(a,b) computes the value \spad{m} of lowest degree
-            ++ such that \spad{m = a*aa = b*bb} for some values
-            ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
-            ++ computed using left-division.
-          rightDivide:   (%, %) -> Record(quotient: %, remainder: %)
-            ++ rightDivide(a,b) 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''.
-          rightQuotient:  (%, %) -> %
-            ++ rightQuotient(a,b) computes 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}.
-            ++ The value \spad{q} is returned.
-          rightRemainder:  (%, %) -> %
-            ++ rightRemainder(a,b) computes 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}.
-            ++ The value \spad{r} is returned.
-          rightExactQuotient:(%, %) -> Union(%, "failed")
-            ++ rightExactQuotient(a,b) computes the value \spad{q}, if it exists
-            ++ such that \spad{a = q*b}.
-          rightGcd:   (%, %) -> %
-            ++ rightGcd(a,b) computes the value \spad{g} of highest degree
-            ++ such that
-            ++    \spad{a = aa*g}
-            ++    \spad{b = bb*g}
-            ++ for some values \spad{aa} and \spad{bb}.
-            ++ The value \spad{g} is computed using right-division.
-          rightExtendedGcd:   (%, %) -> Record(coef1:%, coef2:%, generator:%)
-            ++ rightExtendedGcd(a,b) returns \spad{[c,d]} such that
-            ++ \spad{g = c * a + d * b = rightGcd(a, b)}.
-          leftLcm:   (%, %) -> %
-            ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
-            ++ such that \spad{m = aa*a = bb*b} for some values
-            ++ \spad{aa} and \spad{bb}.  The value \spad{m} is
-            ++ computed using right-division.
- 
-   add
-        coerce(x:R):% == monomial(x, 0)
- 
-        coefficients l ==
-          ans:List(R) := empty()
-          while l ^= 0 repeat
-            ans := concat(leadingCoefficient l, ans)
-            l   := reductum l
-          ans
- 
-        a:R * y:% ==
-          z:% := 0
-          while y ^= 0 repeat
-            z := z + monomial(a * leadingCoefficient y, degree y)
-            y := reductum y
-          z
- 
-        retractIfCan(x:%):Union(R, "failed") ==
-          zero? x or zero? degree x => leadingCoefficient x
-          "failed"
- 
-        if R has IntegralDomain then
-          l exquo a ==
-            ans:% := 0
-            while l ^= 0 repeat
-              (u := (leadingCoefficient(l) exquo a)) case "failed" =>
-                 return "failed"
-              ans := ans + monomial(u::R, degree l)
-              l   := reductum l
-            ans
- 
-        if R has GcdDomain then
-          content l       == gcd coefficients l
-          primitivePart l == (l exquo content l)::%
- 
-        if R has Field then
-          leftEEA:  (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
-          rightEEA: (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
-          ncgcd:    (%, %, (%, %) -> %) -> %
-          nclcm:  (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) -> %
-          exactQuotient: Record(quotient:%, remainder:%) -> Union(%, "failed")
-          extended: (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) ->
-                                          Record(coef1:%, coef2:%, generator:%)
- 
-          leftQuotient(a, b)         == leftDivide(a,b).quotient
-          leftRemainder(a, b)        == leftDivide(a,b).remainder
-          leftExtendedGcd(a, b)      == extended(a, b, leftEEA)
-          rightLcm(a, b)             == nclcm(a, b, leftEEA)
-          rightQuotient(a, b)        == rightDivide(a,b).quotient
-          rightRemainder(a, b)       == rightDivide(a,b).remainder
-          rightExtendedGcd(a, b)     == extended(a, b, rightEEA)
-          leftLcm(a, b)              == nclcm(a, b, rightEEA)
-          leftExactQuotient(a, b)    == exactQuotient leftDivide(a, b)
-          rightExactQuotient(a, b)   == exactQuotient rightDivide(a, b)
-          rightGcd(a, b)             == ncgcd(a, b, rightRemainder)
-          leftGcd(a, b)              == ncgcd(a, b, leftRemainder)
-          exactQuotient qr  == (zero?(qr.remainder) => qr.quotient; "failed")
- 
-          -- returns [g = leftGcd(a, b), c, d, l = rightLcm(a, b)]
-          -- such that g := a c + b d
-          leftEEA(a, b) ==
-            a0 := a
-            u0:% := v:% := 1
-            v0:% := u:% := 0
-            while b ^= 0 repeat
-              qr     := leftDivide(a, b)
-              (a, b) := (b, qr.remainder)
-              (u0, u):= (u, u0 - u * qr.quotient)
-              (v0, v):= (v, v0 - v * qr.quotient)
-            [a, u0, v0, a0 * u]
- 
-          ncgcd(a, b, ncrem) ==
-            zero? a => b
-            zero? b => a
-            degree a < degree b => ncgcd(b, a, ncrem)
-            while b ^= 0 repeat (a, b) := (b, ncrem(a, b))
-            a
- 
-          extended(a, b, eea) ==
-            zero? a => [0, 1, b]
-            zero? b => [1, 0, a]
-            degree a < degree b =>
-              rec := eea(b, a)
-              [rec.coef2, rec.coef1, rec.gcd]
-            rec := eea(a, b)
-            [rec.coef1, rec.coef2, rec.gcd]
- 
-          nclcm(a, b, eea) ==
-            zero? a or zero? b => 0
-            degree a < degree b => nclcm(b, a, eea)
-            rec := eea(a, b)
-            rec.lcm
- 
-          -- returns [g = rightGcd(a, b), c, d, l = leftLcm(a, b)]
-          -- such that g := a c + b d
-          rightEEA(a, b) ==
-            a0 := a
-            u0:% := v:% := 1
-            v0:% := u:% := 0
-            while b ^= 0 repeat
-              qr     := rightDivide(a, b)
-              (a, b) := (b, qr.remainder)
-              (u0, u):= (u, u0 - qr.quotient * u)
-              (v0, v):= (v, v0 - qr.quotient * v)
-            [a, u0, v0, u * a0]
-
-@
 \section{package APPLYORE ApplyUnivariateSkewPolynomial}
 <<package APPLYORE ApplyUnivariateSkewPolynomial>>=
 )abbrev package APPLYORE ApplyUnivariateSkewPolynomial
@@ -545,7 +306,6 @@ UnivariateSkewPolynomial(x:Symbol, R:Ring, sigma:Automorphism R, delta: R -> R):
 <<*>>=
 <<license>>
  
-<<category OREPCAT UnivariateSkewPolynomialCategory>>
 <<package APPLYORE ApplyUnivariateSkewPolynomial>>
 <<domain AUTOMOR Automorphism>>
 <<package OREPCTO UnivariateSkewPolynomialCategoryOps>>
diff --git a/src/algebra/perm.spad.pamphlet b/src/algebra/perm.spad.pamphlet
index 41181aa..67116d0 100644
--- a/src/algebra/perm.spad.pamphlet
+++ b/src/algebra/perm.spad.pamphlet
@@ -9,52 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category PERMCAT PermutationCategory}
-<<category PERMCAT PermutationCategory>>=
-)abbrev category PERMCAT PermutationCategory
-++ Authors:  Holger Gollan, Johannes Grabmeier, Gerhard Schneider
-++ Date Created: 27 July 1989
-++ Date Last Updated: 29 March 1990
-++ Basic Operations: cycle, cycles, eval, orbit
-++ Related Constructors: PermutationGroup, PermutationGroupExamples
-++ Also See: RepresentationTheoryPackage1
-++ AMS Classifications:
-++ Keywords: permutation, symmetric group
-++ References:
-++ Description: PermutationCategory provides a categorial environment
-++  for subgroups of bijections of a set (i.e. permutations)
-
-PermutationCategory(S:SetCategory): Category  ==  Group with
-    cycle   :  List S       ->  %
-      ++ cycle(ls) coerces a cycle {\em ls}, i.e. a list with not
-      ++ repetitions to a permutation, which maps {\em ls.i} to
-      ++ {\em ls.i+1}, indices modulo the length of the list.
-      ++ Error: if repetitions occur.
-    cycles  :  List List S  ->  %
-      ++ cycles(lls) coerces a list list of cycles {\em lls}
-      ++ to a permutation, each cycle being a list with not
-      ++ repetitions, is coerced to the permutation, which maps
-      ++ {\em ls.i} to {\em ls.i+1}, indices modulo the length of the list,
-      ++ then these permutations are mutiplied.
-      ++ Error: if repetitions occur in one cycle.
-    eval  :  (%,S)          ->  S
-      ++ eval(p, el) returns the image of {\em el} under the
-      ++ permutation p.
-    elt  :  (%,S)          ->  S
-      ++ elt(p, el) returns the image of {\em el} under the
-      ++ permutation p.
-    orbit :  (%,S)          ->  Set S
-      ++ orbit(p, el) returns the orbit of {\em el} under the
-      ++ permutation p, i.e. the set which is given by applications of
-      ++ the powers of p to {\em el}.
-    "<" : (%,%)             ->  Boolean
-      ++ p < q is an order relation on permutations.
-      ++ Note: this order is only total if and only if S is totally ordered
-      ++ or S is finite.
-    if S has OrderedSet then OrderedSet
-    if S has Finite then OrderedSet
-
-@
 \section{domain PERM Permutation}
 <<domain PERM Permutation>>=
 )abbrev domain PERM Permutation
diff --git a/src/algebra/ptranfn.spad.pamphlet b/src/algebra/ptranfn.spad.pamphlet
deleted file mode 100644
index 306346d..0000000
--- a/src/algebra/ptranfn.spad.pamphlet
+++ /dev/null
@@ -1,146 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra ptranfn.spad}
-\author{Clifton J. Williamson}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{category PTRANFN PartialTranscendentalFunctions}
-<<category PTRANFN PartialTranscendentalFunctions>>=
-)abbrev category PTRANFN PartialTranscendentalFunctions
-++ Description of a package which provides partial transcendental
-++ functions, i.e. functions which return an answer or "failed"
-++ Author: Clifton J. Williamson
-++ Date Created: 12 February 1990
-++ Date Last Updated: 14 February 1990
-++ Keywords:
-++ Examples:
-++ References:
-++ Description:
-++ This is the description of any package which provides partial
-++ functions on a domain belonging to TranscendentalFunctionCategory.
- 
-PartialTranscendentalFunctions(K): Category == Definition where
-  K :     TranscendentalFunctionCategory
-  NNI ==> NonNegativeInteger
- 
-  Definition ==> with
- 
---% Exponentials and Logarithms
- 
-    nthRootIfCan: (K,NNI) -> Union(K,"failed")
-      ++ nthRootIfCan(z,n) returns the nth root of z if possible,
-      ++ and "failed" otherwise.
-    expIfCan: K -> Union(K,"failed")
-      ++ expIfCan(z) returns exp(z) if possible, and "failed" otherwise.
-    logIfCan: K -> Union(K,"failed")
-      ++ logIfCan(z) returns log(z) if possible, and "failed" otherwise.
- 
---% TrigonometricFunctionCategory
- 
-    sinIfCan : K -> Union(K,"failed")
-      ++ sinIfCan(z) returns sin(z) if possible, and "failed" otherwise.
-    cosIfCan: K -> Union(K,"failed")
-      ++ cosIfCan(z) returns cos(z) if possible, and "failed" otherwise.
-    tanIfCan: K -> Union(K,"failed")
-      ++ tanIfCan(z) returns tan(z) if possible, and "failed" otherwise.
-    cotIfCan: K -> Union(K,"failed")
-      ++ cotIfCan(z) returns cot(z) if possible, and "failed" otherwise.
-    secIfCan: K -> Union(K,"failed")
-      ++ secIfCan(z) returns sec(z) if possible, and "failed" otherwise.
-    cscIfCan: K -> Union(K,"failed")
-      ++ cscIfCan(z) returns csc(z) if possible, and "failed" otherwise.
- 
---% ArcTrigonometricFunctionCategory
- 
-    asinIfCan: K -> Union(K,"failed")
-      ++ asinIfCan(z) returns asin(z) if possible, and "failed" otherwise.
-    acosIfCan: K -> Union(K,"failed")
-      ++ acosIfCan(z) returns acos(z) if possible, and "failed" otherwise.
-    atanIfCan: K -> Union(K,"failed")
-      ++ atanIfCan(z) returns atan(z) if possible, and "failed" otherwise.
-    acotIfCan: K -> Union(K,"failed")
-      ++ acotIfCan(z) returns acot(z) if possible, and "failed" otherwise.
-    asecIfCan: K -> Union(K,"failed")
-      ++ asecIfCan(z) returns asec(z) if possible, and "failed" otherwise.
-    acscIfCan: K -> Union(K,"failed")
-      ++ acscIfCan(z) returns acsc(z) if possible, and "failed" otherwise.
- 
---% HyperbolicFunctionCategory
- 
-    sinhIfCan: K -> Union(K,"failed")
-      ++ sinhIfCan(z) returns sinh(z) if possible, and "failed" otherwise.
-    coshIfCan: K -> Union(K,"failed")
-      ++ coshIfCan(z) returns cosh(z) if possible, and "failed" otherwise.
-    tanhIfCan: K -> Union(K,"failed")
-      ++ tanhIfCan(z) returns tanh(z) if possible, and "failed" otherwise.
-    cothIfCan: K -> Union(K,"failed")
-      ++ cothIfCan(z) returns coth(z) if possible, and "failed" otherwise.
-    sechIfCan: K -> Union(K,"failed")
-      ++ sechIfCan(z) returns sech(z) if possible, and "failed" otherwise.
-    cschIfCan: K -> Union(K,"failed")
-      ++ cschIfCan(z) returns csch(z) if possible, and "failed" otherwise.
- 
---% ArcHyperbolicFunctionCategory
- 
-    asinhIfCan: K -> Union(K,"failed")
-      ++ asinhIfCan(z) returns asinh(z) if possible, and "failed" otherwise.
-    acoshIfCan: K -> Union(K,"failed")
-      ++ acoshIfCan(z) returns acosh(z) if possible, and "failed" otherwise.
-    atanhIfCan: K -> Union(K,"failed")
-      ++ atanhIfCan(z) returns atanh(z) if possible, and "failed" otherwise.
-    acothIfCan: K -> Union(K,"failed")
-      ++ acothIfCan(z) returns acoth(z) if possible, and "failed" otherwise.
-    asechIfCan: K -> Union(K,"failed")
-      ++ asechIfCan(z) returns asech(z) if possible, and "failed" otherwise.
-    acschIfCan: K -> Union(K,"failed")
-      ++ acschIfCan(z) returns acsch(z) if possible, and "failed" otherwise.
-
-@
-\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>>
-
-<<category PTRANFN PartialTranscendentalFunctions>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
diff --git a/src/algebra/puiseux.spad.pamphlet b/src/algebra/puiseux.spad.pamphlet
index 3d1f816..f63575a 100644
--- a/src/algebra/puiseux.spad.pamphlet
+++ b/src/algebra/puiseux.spad.pamphlet
@@ -9,63 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory}
-<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>=
-)abbrev category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory
-++ Author: Clifton J. Williamson
-++ Date Created: 6 February 1990
-++ Date Last Updated: 22 March 1990
-++ Basic Operations:
-++ Related Domains:
-++ Also See:
-++ AMS Classifications:
-++ Keywords: series, Puiseux, Laurent
-++ Examples:
-++ References:
-++ Description:
-++   This is a category of univariate Puiseux series constructed
-++   from univariate Laurent series.  A Puiseux series is represented
-++   by a pair \spad{[r,f(x)]}, where r is a positive rational number and
-++   \spad{f(x)} is a Laurent series.  This pair represents the Puiseux
-++   series \spad{f(x^r)}.
-UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS):_
- Category == Definition where
-  Coef : Ring
-  ULS  : UnivariateLaurentSeriesCategory Coef
-  I  ==> Integer
-  RN ==> Fraction Integer
-
-  Definition ==> Join(UnivariatePuiseuxSeriesCategory(Coef),_
-                      RetractableTo ULS) with
-    puiseux: (RN,ULS) -> %
-      ++ \spad{puiseux(r,f(x))} returns \spad{f(x^r)}.
-    rationalPower: % -> RN
-      ++ \spad{rationalPower(f(x))} returns r where the Puiseux series
-      ++ \spad{f(x) = g(x^r)}.
-    laurentRep  : % -> ULS
-      ++ \spad{laurentRep(f(x))} returns \spad{g(x)} where the Puiseux series
-      ++ \spad{f(x) = g(x^r)} is represented by \spad{[r,g(x)]}.
-    degree: % -> RN
-      ++ \spad{degree(f(x))} returns the degree of the leading term of the
-      ++ Puiseux series \spad{f(x)}, which may have zero as a coefficient.
-    coerce: ULS -> %
-      ++ \spad{coerce(f(x))} converts the Laurent series \spad{f(x)} to a
-      ++ Puiseux series.
-    laurent: % -> ULS
-      ++ \spad{laurent(f(x))} converts the Puiseux series \spad{f(x)} to a
-      ++ Laurent series if possible. Error: if this is not possible.
-    laurentIfCan: % -> Union(ULS,"failed")
-      ++ \spad{laurentIfCan(f(x))} converts the Puiseux series \spad{f(x)}
-      ++ to a Laurent series if possible.
-      ++ If this is not possible, "failed" is returned.
-
-   add
-
-     zero? x == zero? laurentRep x
-     retract(x:%):ULS == laurent x
-     retractIfCan(x:%):Union(ULS,"failed") == laurentIfCan x
-
-@
 \section{domain UPXSCONS UnivariatePuiseuxSeriesConstructor}
 <<domain UPXSCONS UnivariatePuiseuxSeriesConstructor>>=
 )abbrev domain UPXSCONS UnivariatePuiseuxSeriesConstructor
@@ -646,7 +589,6 @@ UnivariatePuiseuxSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
 <<*>>=
 <<license>>
 
-<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>
 <<domain UPXSCONS UnivariatePuiseuxSeriesConstructor>>
 <<domain UPXS UnivariatePuiseuxSeries>>
 <<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>
diff --git a/src/algebra/quat.spad.pamphlet b/src/algebra/quat.spad.pamphlet
index ebb8941..3aa45dd 100644
--- a/src/algebra/quat.spad.pamphlet
+++ b/src/algebra/quat.spad.pamphlet
@@ -5049,189 +5049,6 @@ the result of the preceding example ?
 \newpage
 \chapter{Axiom Algebra Code}
 
-\section{category QUATCAT QuaternionCategory}
-<<category QUATCAT QuaternionCategory>>=
-)abbrev category QUATCAT QuaternionCategory
-++ Author: Robert S. Sutor
-++ Date Created: 23 May 1990
-++ Change History:
-++   10 September 1990
-++ Basic Operations: (Algebra)
-++   abs, conjugate, imagI, imagJ, imagK, norm, quatern, rational,
-++   rational?, real
-++ Related Constructors: Quaternion, QuaternionCategoryFunctions2
-++ Also See: DivisionRing
-++ AMS Classifications: 11R52
-++ Keywords: quaternions, division ring, algebra
-++ Description:
-++   \spadtype{QuaternionCategory} describes the category of quaternions
-++   and implements functions that are not representation specific.
- 
-QuaternionCategory(R: CommutativeRing): Category ==
-  Join(Algebra R, FullyRetractableTo R, DifferentialExtension R,
-   FullyEvalableOver R, FullyLinearlyExplicitRingOver R) with
- 
-     conjugate: $ -> $
-       ++ conjugate(q) negates the imaginary parts of quaternion \spad{q}.
-     imagI:   $ -> R
-       ++ imagI(q) extracts the imaginary i part of quaternion \spad{q}.
-     imagJ:   $ -> R
-       ++ imagJ(q) extracts the imaginary j part of quaternion \spad{q}.
-     imagK:   $ -> R
-       ++ imagK(q) extracts the imaginary k part of quaternion \spad{q}.
-     norm:    $ -> R
-       ++ norm(q) computes the norm of \spad{q} (the sum of the
-       ++ squares of the components).
-     quatern: (R,R,R,R) -> $
-       ++ quatern(r,i,j,k) constructs a quaternion from scalars.
-     real:    $ -> R
-       ++ real(q) extracts the real part of quaternion \spad{q}.
- 
-     if R has EntireRing then EntireRing
-     if R has OrderedSet then OrderedSet
-     if R has Field then DivisionRing
-     if R has ConvertibleTo InputForm then ConvertibleTo InputForm
-     if R has CharacteristicZero then CharacteristicZero
-     if R has CharacteristicNonZero then CharacteristicNonZero
-     if R has RealNumberSystem then
-       abs    : $ -> R
-         ++ abs(q) computes the absolute value of quaternion \spad{q}
-         ++ (sqrt of norm).
-     if R has IntegerNumberSystem then
-       rational?    : $ -> Boolean
-         ++ rational?(q) returns {\it true} if all the imaginary
-         ++ parts of \spad{q} are zero and the real part can be
-         ++ converted into a rational number, and {\it false}
-         ++ otherwise.
-       rational     : $ -> Fraction Integer
-         ++ rational(q) tries to convert \spad{q} into a
-         ++ rational number. Error: if this is not
-         ++ possible. If \spad{rational?(q)} is true, the
-         ++ conversion will be done and the rational number returned.
-       rationalIfCan: $ -> Union(Fraction Integer, "failed")
-         ++ rationalIfCan(q) returns \spad{q} as a rational number,
-         ++ or "failed" if this is not possible.
-         ++ Note: if \spad{rational?(q)} is true, the conversion
-         ++ can be done and the rational number will be returned.
- 
- add
- 
-       characteristic() ==
-         characteristic()$R
-       conjugate x      ==
-         quatern(real x, - imagI x, - imagJ x, - imagK x)
-       map(fn, x)       ==
-         quatern(fn real x, fn imagI x, fn imagJ x, fn imagK x)
-       norm x ==
-         real x * real x + imagI x * imagI x +
-           imagJ x * imagJ x + imagK x * imagK x
-       x = y            ==
-         (real x = real y) and (imagI x = imagI y) and
-           (imagJ x = imagJ y) and (imagK x = imagK y)
-       x + y            ==
-         quatern(real x + real y, imagI x + imagI y,
-           imagJ x + imagJ y, imagK x + imagK y)
-       x - y            ==
-         quatern(real x - real y, imagI x - imagI y,
-           imagJ x - imagJ y, imagK x - imagK y)
-       - x              ==
-         quatern(- real x, - imagI x, - imagJ x, - imagK x)
-       r:R * x:$        ==
-         quatern(r * real x, r * imagI x, r * imagJ x, r * imagK x)
-       n:Integer * x:$  ==
-         quatern(n * real x, n * imagI x, n * imagJ x, n * imagK x)
-       differentiate(x:$, d:R -> R) ==
-         quatern(d real x, d imagI x, d imagJ x, d imagK x)
-       coerce(r:R)      ==
-         quatern(r,0$R,0$R,0$R)
-       coerce(n:Integer)      ==
-         quatern(n :: R,0$R,0$R,0$R)
-       one? x ==
---         one? real x and zero? imagI x and
-         (real x) = 1 and zero? imagI x and
-           zero? imagJ x and zero? imagK x
-       zero? x ==
-         zero? real x and zero? imagI x and
-           zero? imagJ x and zero? imagK x
-       retract(x):R ==
-         not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
-           error "Cannot retract quaternion."
-         real x
-       retractIfCan(x):Union(R,"failed") ==
-         not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
-           "failed"
-         real x
- 
-       coerce(x:$):OutputForm ==
-         part,z : OutputForm
-         y : $
-         zero? x => (0$R) :: OutputForm
-         not zero?(real x) =>
-           y := quatern(0$R,imagI(x),imagJ(x),imagK(x))
-           zero? y => real(x) :: OutputForm
-           (real(x) :: OutputForm) + (y :: OutputForm)
-         -- we know that the real part is 0
-         not zero?(imagI(x)) =>
-           y := quatern(0$R,0$R,imagJ(x),imagK(x))
-           z :=
-             part := "i"::Symbol::OutputForm
---             one? imagI(x) => part
-             (imagI(x) = 1) => part
-             (imagI(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part and i part are 0
-         not zero?(imagJ(x)) =>
-           y := quatern(0$R,0$R,0$R,imagK(x))
-           z :=
-             part := "j"::Symbol::OutputForm
---             one? imagJ(x) => part
-             (imagJ(x) = 1) => part
-             (imagJ(x) :: OutputForm) * part
-           zero? y => z
-           z + (y :: OutputForm)
-         -- we know that the real part and i and j parts are 0
-         part := "k"::Symbol::OutputForm
---         one? imagK(x) => part
-         (imagK(x) = 1) => part
-         (imagK(x) :: OutputForm) * part
- 
-       if R has Field then
-         inv x ==
-           norm x = 0 => error "This quaternion is not invertible."
-           (inv norm x) * conjugate x
- 
-       if R has ConvertibleTo InputForm then
-         convert(x:$):InputForm ==
-           l : List InputForm := [convert("quatern" :: Symbol),
-             convert(real x)$R, convert(imagI x)$R, convert(imagJ x)$R,
-               convert(imagK x)$R]
-           convert(l)$InputForm
- 
-       if R has OrderedSet then
-         x < y ==
-           real x = real y =>
-             imagI x = imagI y =>
-               imagJ x = imagJ y =>
-                 imagK x < imagK y
-               imagJ x < imagJ y
-             imagI x < imagI y
-           real x < real y
- 
-       if R has RealNumberSystem then
-         abs x == sqrt norm x
- 
-       if R has IntegerNumberSystem then
-         rational? x ==
-           (zero? imagI x) and (zero? imagJ x) and (zero? imagK x)
-         rational  x ==
-           rational? x => rational real x
-           error "Not a rational number"
-         rationalIfCan x ==
-           rational? x => rational real x
-           "failed"
-
-@
 \section{domain QUAT Quaternion}
 <<Quaternion.input>>=
 -- quat.spad.pamphlet Quaternion.input
@@ -5721,7 +5538,6 @@ $$
 <<*>>=
 <<license>>
  
-<<category QUATCAT QuaternionCategory>>
 <<domain QUAT Quaternion>>
 <<package QUATCT2 QuaternionCategoryFunctions2>>
 @
diff --git a/src/algebra/reclos.spad.pamphlet b/src/algebra/reclos.spad.pamphlet
index 85889cc..2c39ac3 100644
--- a/src/algebra/reclos.spad.pamphlet
+++ b/src/algebra/reclos.spad.pamphlet
@@ -179,252 +179,6 @@ RealPolynomialUtilitiesPackage(TheField,ThePols) : PUB == PRIV where
            lazyVariations(rest(rest(l)),s,sh)
     
 @
-\section{category RRCC RealRootCharacterizationCategory}
-<<category RRCC RealRootCharacterizationCategory>>=
-)abbrev category RRCC RealRootCharacterizationCategory
-++ Author: Renaud Rioboo
-++ Date Created: summer 1992
-++ Date Last Updated: January 2004
-++ Basic Functions: provides operations with generic real roots of 
-++                  polynomials 
-++ Related Constructors: RealClosure, RightOpenIntervalRootCharacterization
-++ Also See: 
-++ AMS Classifications:
-++ Keywords: Real Algebraic Numbers
-++ References: 
-++ Description:
-++ \axiomType{RealRootCharacterizationCategory} provides common acces
-++ functions for all real root codings.
-RealRootCharacterizationCategory(TheField, ThePols ) : Category == PUB where
-
-   TheField : Join(OrderedRing, Field)
-   ThePols : UnivariatePolynomialCategory(TheField)
-
-   Z ==> Integer
-   N ==> PositiveInteger
-
-   PUB ==>
-     SetCategory with
-
-        sign:                ( ThePols, $ )   ->            Z
-              ++ \axiom{sign(pol,aRoot)} gives the sign of \axiom{pol}
-              ++ interpreted as \axiom{aRoot}
-        zero? :              ( ThePols, $ )   ->         Boolean
-              ++ \axiom{zero?(pol,aRoot)} answers if \axiom{pol}
-              ++ interpreted as \axiom{aRoot} is \axiom{0}
-        negative?:           ( ThePols, $ )   ->         Boolean
-              ++ \axiom{negative?(pol,aRoot)} answers if \axiom{pol}
-              ++ interpreted as \axiom{aRoot} is negative
-        positive?:           ( ThePols, $ )   ->         Boolean
-              ++ \axiom{positive?(pol,aRoot)} answers if \axiom{pol}
-              ++ interpreted as \axiom{aRoot} is positive
-        recip:               ( ThePols, $ )   ->   Union(ThePols,"failed") 
-              ++ \axiom{recip(pol,aRoot)} tries to inverse \axiom{pol}
-              ++ interpreted as \axiom{aRoot}
-        definingPolynomial:         $         ->         ThePols
-              ++ \axiom{definingPolynomial(aRoot)} gives a polynomial
-              ++ such that \axiom{definingPolynomial(aRoot).aRoot = 0} 
-        allRootsOf:              ThePols      ->          List $
-              ++ \axiom{allRootsOf(pol)} creates all the roots of \axiom{pol} 
-              ++ in the Real Closure, assumed in order.
-        rootOf:              ( ThePols, N )   ->      Union($,"failed")
-              ++ \axiom{rootOf(pol,n)} gives the nth root for the order of the
-              ++ Real Closure
-        approximate :  (ThePols,$,TheField)   ->    TheField
-              ++ \axiom{approximate(term,root,prec)} gives an approximation 
-              ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
-
-        relativeApprox :  (ThePols,$,TheField)   ->    TheField
-              ++ \axiom{approximate(term,root,prec)} gives an approximation 
-              ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
-
-      add
-
-        zero?(toTest, rootChar) == 
-          sign(toTest, rootChar) = 0
-                
-        negative?(toTest, rootChar) == 
-          sign(toTest, rootChar) < 0              
-        
-        positive?(toTest, rootChar) == 
-          sign(toTest, rootChar) > 0
-
-        rootOf(pol,n) ==
-          liste:List($):= allRootsOf(pol)
-          # liste > n => "failed"
-          liste.n
-
-        recip(toInv,rootChar) ==
-          degree(toInv) = 0 => 
-            res := recip(leadingCoefficient(toInv))
-            if (res case "failed") then "failed" else (res::TheField::ThePols)
-          defPol := definingPolynomial(rootChar)
-          d := principalIdeal([defPol,toInv])
-          zero?(d.generator,rootChar) => "failed"
-          if (degree(d.generator) ^= 0 )
-          then
-            defPol := (defPol exquo (d.generator))::ThePols
-            d := principalIdeal([defPol,toInv])
-          d.coef.2
-
-@
-\section{category RCFIELD RealClosedField}
-<<category RCFIELD RealClosedField>>=
-)abbrev category RCFIELD RealClosedField
-++ Author: Renaud Rioboo
-++ Date Created: may 1993
-++ Date Last Updated: January 2004
-++ Basic Functions: provides computations with generic real roots of 
-++                  polynomials 
-++ Related Constructors: SimpleOrderedAlgebraicExtension, RealClosure
-++ Also See: 
-++ AMS Classifications:
-++ Keywords: Real Algebraic Numbers
-++ References: 
-++ Description:
-++ \axiomType{RealClosedField} provides common acces
-++ functions for all real closed fields.
-RealClosedField : Category == PUB where
-
-    E ==> OutputForm
-    SUP ==> SparseUnivariatePolynomial
-    OFIELD ==> Join(OrderedRing,Field)
-    PME ==> SUP($)
-    N ==> NonNegativeInteger
-    PI ==> PositiveInteger
-    RN ==> Fraction(Integer)
-    Z  ==> Integer
-    POLY ==> Polynomial
-    PACK ==> SparseUnivariatePolynomialFunctions2
-
-    PUB == Join(CharacteristicZero,
-                OrderedRing,
-                CommutativeRing,
-                Field,
-                FullyRetractableTo(Fraction(Integer)),
-                Algebra Integer,
-                Algebra(Fraction(Integer)),
-                RadicalCategory) with
-
-        mainForm :   $ -> Union(E,"failed")
-             ++ \axiom{mainForm(x)} is the main algebraic quantity name of 
-             ++ \axiom{x}
-
-        mainDefiningPolynomial :   $ -> Union(PME,"failed")
-             ++ \axiom{mainDefiningPolynomial(x)} is the defining 
-             ++ polynomial for the main algebraic quantity of \axiom{x}
-
-        mainValue :   $ -> Union(PME,"failed")
-             ++ \axiom{mainValue(x)} is the expression of \axiom{x} in terms
-             ++ of \axiom{SparseUnivariatePolynomial($)} 
-
-        rootOf:          (PME,PI,E)           -> Union($,"failed")
-             ++ \axiom{rootOf(pol,n,name)} creates the nth root for the order
-             ++ of \axiom{pol} and names it \axiom{name}
-
-        rootOf:          (PME,PI)             -> Union($,"failed")
-             ++ \axiom{rootOf(pol,n)} creates the nth root for the order
-             ++ of \axiom{pol} and gives it unique name
-
-        allRootsOf:       PME                ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        allRootsOf:       (SUP(RN))          ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        allRootsOf:       (SUP(Z))          ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        allRootsOf:       (POLY($))         ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        allRootsOf:       (POLY(RN))        ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        allRootsOf:       (POLY(Z))         ->  List $
-             ++ \axiom{allRootsOf(pol)} creates all the roots
-             ++ of \axiom{pol} naming each uniquely
-
-        sqrt:            ($,N)                ->     $
-             ++ \axiom{sqrt(x,n)} is \axiom{x ** (1/n)}
-
-        sqrt:              $                  ->     $
-             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
-
-        sqrt:             RN                  ->     $
-             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
-
-        sqrt:              Z                  ->     $
-             ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
-
-        rename! :        ($,E)                ->     $
-             ++ \axiom{rename!(x,name)} changes the way \axiom{x} is printed
-
-        rename :         ($,E)                ->     $
-             ++ \axiom{rename(x,name)} gives a new number that prints as name
-
-        approximate:       ($,$) -> RN
-              ++ \axiom{approximate(n,p)} gives an approximation of \axiom{n}
-              ++ that has precision \axiom{p}
-
-      add
-
-        sqrt(a:$):$ == sqrt(a,2)
-
-        sqrt(a:RN):$ == sqrt(a::$,2)
-
-        sqrt(a:Z):$ == sqrt(a::$,2)
-
-        characteristic() == 0
-
-        rootOf(pol,n,o) == 
-          r := rootOf(pol,n)
-          r case "failed" => "failed"
-          rename!(r,o)
-
-        rootOf(pol,n) ==
-          liste:List($):= allRootsOf(pol)
-          # liste > n => "failed"
-          liste.n
-
-
-        sqrt(x,n) ==
-          n = 0 => 1
-          n = 1 => x
-          zero?(x) => 0
-          one?(x) => 1 
-          if odd?(n)
-          then
-            r := rootOf(monomial(1,n) - (x :: PME), 1)
-          else
-            r := rootOf(monomial(1,n) - (x :: PME), 2)
-          r case "failed" => error "no roots"
-          n = 2 => rename(r,root(x::E)$E)
-          rename(r,root(x :: E, n :: E)$E)
-
-        (x : $) ** (rn : RN) == sqrt(x**numer(rn),denom(rn)::N)
-
-        nthRoot(x, n) == 
-          zero?(n) => x
-          negative?(n) => inv(sqrt(x,(-n) :: N))
-          sqrt(x,n :: N)
-
-        allRootsOf(p:SUP(RN)) == allRootsOf(map(#1 :: $ ,p)$PACK(RN,$))
-
-        allRootsOf(p:SUP(Z)) == allRootsOf(map(#1 :: $ ,p)$PACK(Z,$))
-
-        allRootsOf(p:POLY($)) == allRootsOf(univariate(p))
-
-        allRootsOf(p:POLY(RN)) == allRootsOf(univariate(p))
-
-        allRootsOf(p:POLY(Z)) == allRootsOf(univariate(p))
-
-@
 \section{domain ROIRC RightOpenIntervalRootCharacterization}
 \subsection{makeChar performance problem}
 The following lines of code, which check for a possible error,
@@ -2410,8 +2164,6 @@ RealClosure(TheField): PUB == PRIV where
 <<*>>=
 <<license>>
 <<package POLUTIL RealPolynomialUtilitiesPackage>>
-<<category RRCC RealRootCharacterizationCategory>>
-<<category RCFIELD RealClosedField>>
 <<domain ROIRC RightOpenIntervalRootCharacterization>>
 <<domain RECLOS RealClosure>>
 @
diff --git a/src/algebra/si.spad.pamphlet b/src/algebra/si.spad.pamphlet
index 4ff736c..2523adf 100644
--- a/src/algebra/si.spad.pamphlet
+++ b/src/algebra/si.spad.pamphlet
@@ -9,187 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category INS IntegerNumberSystem}
-<<dot>>=
-"INS" -> "UFD"
-"IntegerNumberSystem()" -> "UniqueFactorizationDomain()"
-"INS" -> "EUCDOM"
-"IntegerNumberSystem()" -> "EuclideanDomain()"
-"INS" -> "OINTDOM"
-"IntegerNumberSystem()" -> "OrderedIntegralDomain()"
-"INS" -> "DIFRING"
-"IntegerNumberSystem()" -> "DifferentialRing()"
-"INS" -> "KONVERT"
-"IntegerNumberSystem()" -> "ConvertibleTo(Integer)"
-"IntegerNumberSystem()" -> "ConvertibleTo(InputForm)"
-"IntegerNumberSystem()" -> "ConvertibleTo(Pattern(Integer))"
-"INS" -> "RETRACT"
-"IntegerNumberSystem()" -> "RetractableTo(Integer)"
-"INS" -> "LINEXP"
-"IntegerNumberSystem()" -> "LinearlyExplicitRingOver(Integer)"
-"INS" -> "PATMAB"
-"IntegerNumberSystem()" -> "PatternMatchable(Integer)"
-"INS" -> "CFCAT"
-"IntegerNumberSystem()" -> "CombinatorialFunctionCategory()"
-"INS" -> "REAL"
-"IntegerNumberSystem()" -> "RealConstant()"
-"INS" -> "CHARZ"
-"IntegerNumberSystem()" -> "CharacteristicZero()"
-"INS" -> "STEP"
-"IntegerNumberSystem()" -> "StepThrough()"
-@
-<<category INS IntegerNumberSystem>>=
-)abbrev category INS IntegerNumberSystem
-++ Author: Stephen M. Watt
-++ Date Created:
-++   January 1988
-++ Change History:
-++ Basic Operations:
-++   addmod, base, bit?, copy, dec, even?, hash, inc, invmod, length, mask,
-++   positiveRemainder, symmetricRemainder, multiplicativeValuation, mulmod,
-++   odd?, powmod, random, rational, rational?, rationalIfCan, shift, submod
-++ Description:  An \spad{IntegerNumberSystem} is a model for the integers.
-IntegerNumberSystem(): Category ==
-  Join(UniqueFactorizationDomain, EuclideanDomain, OrderedIntegralDomain,
-         DifferentialRing, ConvertibleTo Integer, RetractableTo Integer,
-           LinearlyExplicitRingOver Integer, ConvertibleTo InputForm,
-             ConvertibleTo Pattern Integer, PatternMatchable Integer,
-               CombinatorialFunctionCategory, RealConstant,
-                 CharacteristicZero, StepThrough) with
-   odd?     : % -> Boolean
-      ++ odd?(n) returns true if and only if n is odd.
-   even?    : % -> Boolean
-      ++ even?(n) returns true if and only if n is even.
-   multiplicativeValuation
-      ++ euclideanSize(a*b) returns \spad{euclideanSize(a)*euclideanSize(b)}.
-   base     : () -> %
-      ++ base() returns the base for the operations of \spad{IntegerNumberSystem}.
-   length   : % -> %
-      ++ length(a) length of \spad{a} in digits.
-   shift    : (%, %) -> %
-      ++ shift(a,i) shift \spad{a} by i digits.
-   bit?     : (%, %) -> Boolean
-      ++ bit?(n,i) returns true if and only if i-th bit of n is a 1.
-   positiveRemainder     : (%, %) -> %
-      ++ positiveRemainder(a,b) (where \spad{b > 1}) yields r
-      ++ where \spad{0 <= r < b} and \spad{r == a rem b}.
-   symmetricRemainder     : (%, %) -> %
-      ++ symmetricRemainder(a,b) (where \spad{b > 1}) yields r
-      ++ where \spad{ -b/2 <= r < b/2 }.
-   rational?: % -> Boolean
-      ++ rational?(n) tests if n is a rational number
-      ++ (see \spadtype{Fraction Integer}).
-   rational : % -> Fraction Integer
-      ++ rational(n) creates a rational number (see \spadtype{Fraction Integer})..
-   rationalIfCan: % -> Union(Fraction Integer, "failed")
-      ++ rationalIfCan(n) creates a rational number, or returns "failed" if this is not possible.
-   random   : () -> %
-      ++ random() creates a random element.
-   random   : % -> %
-      ++ random(a) creates a random element from 0 to \spad{n-1}.
-   hash     : % -> %
-      ++ hash(n) returns the hash code of n.
-   copy     : % -> %
-      ++ copy(n) gives a copy of n.
-   inc      : % -> %
-      ++ inc(x) returns \spad{x + 1}.
-   dec      : % -> %
-      ++ dec(x) returns \spad{x - 1}.
-   mask     : % -> %
-      ++ mask(n) returns \spad{2**n-1} (an n bit mask).
-   addmod   : (%,%,%) -> %
-      ++ addmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a+b mod p}.
-   submod   : (%,%,%) -> %
-      ++ submod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a-b mod p}.
-   mulmod   : (%,%,%) -> %
-      ++ mulmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a*b mod p}.
-   powmod   : (%,%,%) -> %
-      ++ powmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a**b mod p}.
-   invmod   : (%,%) -> %
-      ++ invmod(a,b), \spad{0<=a<b>1}, \spad{(a,b)=1} means \spad{1/a mod b}.
-   canonicalUnitNormal
---   commutative("*")    -- follows from the above
-
- add
-   characteristic()         == 0
-   differentiate x          == 0
-   even? x                  == not odd? x
-   positive? x              == x > 0
-   copy x                   == x
-   bit?(x, i)               == odd? shift(x, -i)
-   mask n                   == dec shift(1, n)
-   rational? x              == true
-   euclideanSize(x)         ==
-        x=0 => error "euclideanSize called on zero"
-        x<0 => (-convert(x)@Integer)::NonNegativeInteger
-        convert(x)@Integer::NonNegativeInteger
-   convert(x:%):Float       == (convert(x)@Integer)::Float
-   convert(x:%):DoubleFloat  == (convert(x)@Integer)::DoubleFloat
-   convert(x:%):InputForm   == convert(convert(x)@Integer)
-   retract(x:%):Integer     == convert(x)@Integer
-   convert(x:%):Pattern(Integer)== convert(x)@Integer ::Pattern(Integer)
-   factor x          == factor(x)$IntegerFactorizationPackage(%)
-   squareFree x      == squareFree(x)$IntegerFactorizationPackage(%)
-   prime? x          == prime?(x)$IntegerPrimesPackage(%)
-   factorial x       == factorial(x)$IntegerCombinatoricFunctions(%)
-   binomial(n, m)    == binomial(n, m)$IntegerCombinatoricFunctions(%)
-   permutation(n, m) == permutation(n,m)$IntegerCombinatoricFunctions(%)
-   retractIfCan(x:%):Union(Integer, "failed") == convert(x)@Integer
-
-   init() == 0
-
-   -- iterates in order 0,1,-1,2,-2,3,-3,...
-   nextItem(n) ==
-     zero? n => 1
-     n>0 => -n
-     1-n
-
-   patternMatch(x, p, l) ==
-     patternMatch(x, p, l)$PatternMatchIntegerNumberSystem(%)
-
-   rational(x:%):Fraction(Integer) ==
-     (convert(x)@Integer)::Fraction(Integer)
-
-   rationalIfCan(x:%):Union(Fraction Integer, "failed") ==
-     (convert(x)@Integer)::Fraction(Integer)
-
-   symmetricRemainder(x, n) ==
-      r := x rem n
-      r = 0 => r
-      if n < 0 then n:=-n
-      r > 0 =>
-         2 * r > n => r - n
-         r
-      2*r + n <= 0 => r + n
-      r
-
-   invmod(a, b) ==
-      if negative? a then a := positiveRemainder(a, b)
-      c := a; c1:% := 1
-      d := b; d1:% := 0
-      while not zero? d repeat
-         q := c quo d
-         r := c-q*d
-         r1 := c1-q*d1
-         c := d; c1 := d1
-         d := r; d1 := r1
---      not one? c => error "inverse does not exist"
-      not (c = 1) => error "inverse does not exist"
-      negative? c1 => c1 + b
-      c1
-
-   powmod(x, n, p) ==
-      if negative? x then x := positiveRemainder(x, p)
-      zero? x => 0
-      zero? n => 1
-      y:% := 1
-      z := x
-      repeat
-         if odd? n then y := mulmod(y, z, p)
-         zero?(n := shift(n, -1)) => return y
-         z := mulmod(z, z, p)
-
-@
 \section{domain SINT SingleInteger}
 The definition of {\bf one?} has been rewritten 
 as it relies on calling {\bf ONEP} which is a function specific
diff --git a/src/input/r20bugs.input.pamphlet b/src/input/r20bugs.input.pamphlet
index d91d6ff..2fa8660 100644
--- a/src/input/r20bugs.input.pamphlet
+++ b/src/input/r20bugs.input.pamphlet
@@ -196,8 +196,7 @@ positiveRemainder(-1::SINT,-5::SINT)
 complexRoots([u**2-v+1,v**2-4],[u,v],0.01)
 --R 
 --R
---R   (1)
---R   [[1.732421875 %i,- 2.0],[- 1.732421875 %i,- 2.0],[- 1.0,2.0],[1.0,2.0]]
+--R   (1)  [[1.73046875 %i,- 2.0],[- 1.73046875 %i,- 2.0],[- 1.0,2.0],[1.0,2.0]]
 --R                                                Type: List List Complex Float
 --E 17
 
