diff --git a/books/bookvol10.2.pamphlet b/books/bookvol10.2.pamphlet
index b200ff8..0b5d3db 100644
--- a/books/bookvol10.2.pamphlet
+++ b/books/bookvol10.2.pamphlet
@@ -2610,6 +2610,7 @@ digraph pic {
 \pageto{FunctionSpace}{FS}
 \pageto{MonogenicAlgebra}{MONOGEN}
 \pageto{OctonionCategory}{OC}
+\pageto{SquareMatrixCategory}{SMATCAT}
 \pagefrom{RetractableTo}{RETRACT}
 
 {\bf Exports:}\\
@@ -4759,6 +4760,7 @@ digraph pic {
 \pageto{BagAggregate}{BGAGG}
 \pageto{Collection}{CLAGG}
 \pageto{IndexedAggregate}{IXAGG}
+\pageto{RectangularMatrixCategory}{RMATCAT}
 \pageto{RecursiveAggregate}{RCAGG}
 \pageto{TwoDimensionalArrayCategory}{ARR2CAT}
 \pagefrom{Aggregate}{AGG}
@@ -4949,6 +4951,11 @@ HomogeneousAggregate(S:Type): Category == Aggregate with
  [color=lightblue,href="bookvol10.2.pdf#nameddest=HOAGG"];
 "HomogeneousAggregate(a:Type)" -> "Aggregate()"
 
+"HomogeneousAggregate(Ring)"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=HOAGG"];
+"HomogeneousAggregate(Ring)"
+  -> "HomogeneousAggregate(a:Type)"
+
 @
 <<HOAGG.dotpic>>=
 digraph pic {
@@ -9794,6 +9801,7 @@ the first element of a 'Row' is the same as the index of the
 first column in an array and vice versa.
 
 {\bf See:}\\
+\pageto{MatrixCategory}{MATCAT}
 \pagefrom{HomogeneousAggregate}{HOAGG}
 
 {\bf Exports:}\\
@@ -9876,9 +9884,9 @@ These are directly exported but not implemented:
 These are implemented by this category:
 \begin{verbatim}
  any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- copy : % -> %
  coerce : % -> OutputForm if R has SETCAT
  column : (%,Integer) -> Col          
+ copy : % -> %
  count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
  count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
  elt : (%,Integer,Integer,R) -> R     
@@ -13961,6 +13969,7 @@ AbelianGroup(): Category == CancellationAbelianMonoid with
 "AbelianGroup()"
  [color=lightblue,href="bookvol10.2.pdf#nameddest=ABELGRP"];
 "AbelianGroup()" -> "CancellationAbelianMonoid()"
+"AbelianGroup()" -> "RepeatedDoubling(AbelianGroup)"
 
 @
 <<ABELGRP.dotpic>>=
@@ -13969,22 +13978,6 @@ digraph pic {
  bgcolor="#FFFF66";
  node [shape=box, color=white, style=filled];
 
-"NonAssociativeRng()" [color=lightblue];
-"NonAssociativeRng()" -> "AbelianGroup()"
-"NonAssociativeRng()" -> "Monad()"
-
-"Monad()" [color=lightblue];
-"Monad()" -> "SETCAT..."
-"Monad()" -> "RepeatedSquaring(Monad)"
-
-"RepeatedSquaring(Monad)" [color="#00EE00"];
-"RepeatedSquaring(Monad)" -> "RepeatedSquaring(a:SetCategory)"
-
-"RepeatedSquaring(a:SetCategory)" [color="#00EE00"];
-"RepeatedSquaring(a:SetCategory)" -> "Package"
-
-"Package" [color="#00EE00"];
-
 "AbelianGroup()" [color=lightblue];
 "AbelianGroup()" -> "CancellationAbelianMonoid()"
 "AbelianGroup()" -> "RepeatedDoubling(AbelianGroup)"
@@ -21898,6 +21891,9 @@ digraph pic {
 \pageto{EntireRing}{ENTIRER}
 \pageto{FreeModuleCat}{FMCAT}
 \pageto{Module}{MODULE}
+\pageto{MonogenicLinearOperator}{MLO}
+\pageto{RectangularMatrixCategory}{RMATCAT}
+\pageto{SquareMatrixCategory}{SMATCAT}
 \pageto{XAlgebra}{XALG}
 \pagefrom{LeftModule}{LMODULE}
 \pagefrom{RightModule}{RMODULE}
@@ -23073,6 +23069,7 @@ digraph pic {
 \pageto{FunctionSpace}{FS}
 \pageto{LeftAlgebra}{LALG}
 \pageto{LinearlyExplicitRingOver}{LINEXP}
+\pageto{MonogenicLinearOperator}{MLO}
 \pageto{OrderedRing}{ORDRING}
 \pageto{PartialDifferentialRing}{PDRING}
 \pageto{XAlgebra}{XALG}
@@ -23155,9 +23152,6 @@ These exports come from \refto{Monoid}():
  ?^? : (%,NonNegativeInteger) -> %
 \end{verbatim}
 
-TPDHERE: Note that none of the exports of LeftModule are needed.
-Perhaps this can be eliminated.
-
 <<category RING Ring>>=
 )abbrev category RING Ring
 ++ Author:
@@ -25905,6 +25899,375 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{RectangularMatrixCategory}{RMATCAT}
+\pagepic{ps/v102rectangularmatrixcategory.ps}{RMATCAT}{0.45}
+
+{\bf See:}\\
+\pageto{SquareMatrixCategory}{SMATCAT}
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{HomogeneousAggregate}{HOAGG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{RMATCAT}{0} &
+\cross{RMATCAT}{antisymmetric?} &
+\cross{RMATCAT}{any?} &
+\cross{RMATCAT}{coerce} &
+\cross{RMATCAT}{column} \\
+\cross{RMATCAT}{copy} &
+\cross{RMATCAT}{count} &
+\cross{RMATCAT}{diagonal?} &
+\cross{RMATCAT}{elt} &
+\cross{RMATCAT}{empty} \\
+\cross{RMATCAT}{empty?} &
+\cross{RMATCAT}{eq?} &
+\cross{RMATCAT}{eval} &
+\cross{RMATCAT}{every?} &
+\cross{RMATCAT}{exquo} \\
+\cross{RMATCAT}{hash} &
+\cross{RMATCAT}{latex} &
+\cross{RMATCAT}{less?} &
+\cross{RMATCAT}{listOfLists} &
+\cross{RMATCAT}{map} \\
+\cross{RMATCAT}{map!} &
+\cross{RMATCAT}{matrix} &
+\cross{RMATCAT}{maxColIndex} &
+\cross{RMATCAT}{maxRowIndex} &
+\cross{RMATCAT}{member?} \\
+\cross{RMATCAT}{members} &
+\cross{RMATCAT}{minColIndex} &
+\cross{RMATCAT}{minRowIndex} &
+\cross{RMATCAT}{more?} &
+\cross{RMATCAT}{ncols} \\
+\cross{RMATCAT}{nrows} &
+\cross{RMATCAT}{nullSpace} &
+\cross{RMATCAT}{nullity} &
+\cross{RMATCAT}{parts} &
+\cross{RMATCAT}{qelt} \\
+\cross{RMATCAT}{rank} &
+\cross{RMATCAT}{row} &
+\cross{RMATCAT}{rowEchelon} &
+\cross{RMATCAT}{sample} &
+\cross{RMATCAT}{size?} \\
+\cross{RMATCAT}{square?} &
+\cross{RMATCAT}{subtractIfCan} &
+\cross{RMATCAT}{symmetric?} &
+\cross{RMATCAT}{zero?} &
+\cross{RMATCAT}{\#?} \\
+\cross{RMATCAT}{?*?} &
+\cross{RMATCAT}{?/?} &
+\cross{RMATCAT}{?+?} &
+\cross{RMATCAT}{?-?} &
+\cross{RMATCAT}{-?} \\
+\cross{RMATCAT}{?=?} &
+\cross{RMATCAT}{?\~{}=?} &&&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{RMATCAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{RMATCAT}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{RMATCAT}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\item {\bf nil}
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ column : (%,Integer) -> Col
+ elt : (%,Integer,Integer) -> R
+ elt : (%,Integer,Integer,R) -> R     
+ exquo : (%,R) -> Union(%,"failed") if R has INTDOM
+ listOfLists : % -> List List R
+ map : (((R,R) -> R),%,%) -> %        
+ map : ((R -> R),%) -> %
+ maxColIndex : % -> Integer
+ maxRowIndex : % -> Integer           
+ matrix : List List R -> %            
+ minColIndex : % -> Integer
+ minRowIndex : % -> Integer           
+ nullity : % -> NonNegativeInteger if R has INTDOM
+ nullSpace : % -> List Col if R has INTDOM
+ qelt : (%,Integer,Integer) -> R
+ rank : % -> NonNegativeInteger if R has INTDOM
+ row : (%,Integer) -> Row             
+ rowEchelon : % -> % if R has EUCDOM
+ ?/? : (%,R) -> % if R has FIELD
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ antisymmetric? : % -> Boolean
+ diagonal? : % -> Boolean
+ ncols : % -> NonNegativeInteger
+ nrows : % -> NonNegativeInteger      
+ square? : % -> Boolean               
+ symmetric? : % -> Boolean
+\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
+ ?*? : (R,%) -> %
+ ?*? : (%,R) -> %                     
+ ?*? : (PositiveInteger,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (Integer,%) -> %               
+ ?=? : (%,%) -> Boolean
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+\end{verbatim}
+
+These exports come from \refto{HomogeneousAggregate}(Ring)"
+\begin{verbatim}
+ any? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ copy : % -> %                        
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ empty : () -> %                      
+ empty? : % -> Boolean
+ eq? : (%,%) -> Boolean               
+ eval : (%,List Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,Equation R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,R,R) -> % if R has EVALAB R and R has SETCAT
+ eval : (%,List R,List R) -> % if R has EVALAB R and R has SETCAT
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ less? : (%,NonNegativeInteger) -> Boolean
+ map! : ((R -> R),%) -> % if $ has shallowlyMutable
+ members : % -> List R if $ has finiteAggregate
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ more? : (%,NonNegativeInteger) -> Boolean
+ parts : % -> List R if $ has finiteAggregate
+ size? : (%,NonNegativeInteger) -> Boolean
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+\end{verbatim}
+
+<<category RMATCAT RectangularMatrixCategory>>=
+)abbrev category RMATCAT RectangularMatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: RectangularMatrix(m,n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++   \spadtype{RectangularMatrixCategory} is a category of matrices of fixed
+++   dimensions.  The dimensions of the matrix will be parameters of the
+++   domain.  Domains in this category will be R-modules and will be
+++   non-mutable.
+RectangularMatrixCategory(m,n,R,Row,Col): Category == Definition where
+  m,n : NonNegativeInteger
+  R   : Ring
+  Row : DirectProductCategory(n,R)
+  Col : DirectProductCategory(m,R)
+
+  Definition ==> Join(BiModule(R,R),HomogeneousAggregate(R)) with
+
+    finiteAggregate
+      ++ matrices are finite
+
+    if R has CommutativeRing then Module(R)
+
+--% Matrix creation
+
+    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.
+
+--% Predicates
+
+    square?  : % -> Boolean
+      ++ \spad{square?(m)} returns true if m is a square matrix (i.e. 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 \spad{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 \spad{i} and j)
+      ++ and false otherwise.
+
+--% Size inquiries
+
+    minRowIndex : % -> Integer
+      ++ \spad{minRowIndex(m)} returns the index of the 'first' row of the
+      ++ matrix m.
+    maxRowIndex : % -> Integer
+      ++ \spad{maxRowIndex(m)} returns the index of the 'last' row of the
+      ++ matrix m.
+    minColIndex : % -> Integer
+      ++ \spad{minColIndex(m)} returns the index of the 'first' column of the
+      ++ matrix m.
+    maxColIndex : % -> Integer
+      ++ \spad{maxColIndex(m)} returns the index of the 'last' column of the
+      ++ matrix m.
+    nrows : % -> NonNegativeInteger
+      ++ \spad{nrows(m)} returns the number of rows in the matrix m.
+    ncols : % -> NonNegativeInteger
+      ++ \spad{ncols(m)} returns the number of columns in the matrix m.
+
+--% Part extractions
+
+    listOfLists: % -> List List R
+      ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
+      ++ of lists.
+    elt: (%,Integer,Integer) -> R
+      ++ \spad{elt(m,i,j)} returns the element in the \spad{i}th row and
+      ++ \spad{j}th column of the matrix m.
+      ++ Error: if indices are outside the proper
+      ++ ranges.
+    qelt: (%,Integer,Integer) -> R
+      ++ \spad{qelt(m,i,j)} returns the element in the \spad{i}th row and
+      ++ \spad{j}th column of
+      ++ the matrix m. Note: there is NO error check to determine if indices 
+      ++ are in the proper ranges.
+    elt: (%,Integer,Integer,R) -> R
+      ++ \spad{elt(m,i,j,r)} returns the element in the \spad{i}th row and
+      ++ \spad{j}th column of the matrix m, if m has an \spad{i}th row and a
+      ++ \spad{j}th column, and returns r otherwise.
+    row: (%,Integer) -> Row
+      ++ \spad{row(m,i)} returns the \spad{i}th row of the matrix m.
+      ++ Error: if the index is outside the proper range.
+    column: (%,Integer) -> Col
+      ++ \spad{column(m,j)} returns the \spad{j}th column of the matrix m.
+      ++ Error: if the index outside the proper range.
+
+--% Map and Zip
+
+    map: (R -> R,%) -> %
+      ++ \spad{map(f,a)} returns b, where \spad{b(i,j) = a(i,j)} for all i, j.
+    map:((R,R) -> R,%,%) -> %
+      ++ \spad{map(f,a,b)} returns c, where c is such that
+      ++ \spad{c(i,j) = f(a(i,j),b(i,j))} for all \spad{i}, j.
+
+--% Arithmetic
+
+    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.
+   add
+     nrows x == m
+
+     ncols x == n
+
+     square? x == m = n
+
+     diagonal? x ==
+       not square? x => false
+       for i in minRowIndex x .. maxRowIndex x repeat
+         for j in minColIndex x .. maxColIndex x
+           | (j - minColIndex x) ^= (i - minRowIndex x) repeat
+             not zero? qelt(x, i, j) => return false
+       true
+
+     symmetric? x ==
+       m ^= n => false
+       mr := minRowIndex x; mc := minColIndex x
+       for i in 0..(n - 1) repeat
+         for j in (i + 1)..(n - 1) repeat
+           qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
+       true
+
+     antisymmetric? x ==
+       m ^= n => false
+       mr := minRowIndex x; mc := minColIndex x
+       for i in 0..(n - 1) repeat
+         for j in i..(n - 1) repeat
+           qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
+             return false
+       true
+
+@
+<<RMATCAT.dotabb>>=
+"RMATCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RMATCAT"];
+"RMATCAT" -> "BMODULE"
+"RMATCAT" -> "HOAGG"
+
+@
+<<RMATCAT.dotfull>>=
+"RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=RMATCAT"];
+"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))"
+  -> "HomogeneousAggregate(Ring)"
+
+@
+<<RMATCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"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..."
+
+"HOAGG..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+
+"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..."
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{XAlgebra}{XALG}
 \pagepic{ps/v102xalgebra.ps}{XALG}{0.70}
 
@@ -26088,6 +26451,7 @@ digraph pic {
 \pageto{DifferentialPolynomialCategory}{DPOLCAT}
 \pageto{DirectProductCategory}{DIRPCAT}
 \pageto{QuotientFieldCategory}{QFCAT}
+\pageto{SquareMatrixCategory}{SMATCAT}
 \pageto{UnivariatePolynomialCategory}{UPOLYC}
 \pagefrom{PartialDifferentialRing}{PDRING}
 \pagefrom{Ring}{RING}
@@ -26687,6 +27051,7 @@ digraph pic {
 \pageto{MonogenicAlgebra}{MONOGEN}
 \pageto{PolynomialCategory}{POLYCAT}
 \pageto{QuotientFieldCategory}{QFCAT}
+\pageto{SquareMatrixCategory}{SMATCAT}
 \pagefrom{LinearlyExplicitRingOver}{LINEXP}
 
 {\bf Exports:}\\
@@ -26870,6 +27235,7 @@ digraph pic {
 \pageto{Algebra}{ALGEBRA}
 \pageto{LieAlgebra}{LIECAT}
 \pageto{NonAssociativeAlgebra}{NAALG}
+\pageto{RectangularMatrixCategory}{RMATCAT}
 \pageto{VectorSpace}{VSPACE}
 \pagefrom{BiModule}{BMODULE}
 
@@ -28417,6 +28783,7 @@ digraph pic {
 \pageto{FiniteRankAlgebra}{FINRALG}
 \pageto{FunctionSpace}{FS}
 \pageto{IntegralDomain}{INTDOM}
+\pageto{MonogenicLinearOperator}{MLO}
 \pageto{OctonionCategory}{OC}
 \pageto{QuotientFieldCategory}{QFCAT}
 \pagefrom{Module}{MODULE}
@@ -28936,6 +29303,514 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\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>>=
+<<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}
 
@@ -31515,6 +32390,239 @@ digraph pic {
 }
 
 @
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{MonogenicLinearOperator}{MLO}
+\pagepic{ps/v102monogeniclinearoperator.ps}{MLO}{0.60}
+
+{\bf See:}\\
+\pagefrom{Algebra}{ALGEBRA}
+\pagefrom{BiModule}{BMODULE}
+\pagefrom{Ring}{RING}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+\cross{MLO}{0} &
+\cross{MLO}{1} &
+\cross{MLO}{characteristic} &
+\cross{MLO}{coefficient} \\
+\cross{MLO}{coerce} &
+\cross{MLO}{degree} &
+\cross{MLO}{hash} &
+\cross{MLO}{latex} \\
+\cross{MLO}{leadingCoefficient} &
+\cross{MLO}{minimumDegree} &
+\cross{MLO}{monomial} &
+\cross{MLO}{one?} \\
+\cross{MLO}{recip} &
+\cross{MLO}{reductum} &
+\cross{MLO}{sample} &
+\cross{MLO}{subtractIfCan} \\
+\cross{MLO}{zero?} &
+\cross{MLO}{?*?} &
+\cross{MLO}{?**?} &
+\cross{MLO}{?+?} \\
+\cross{MLO}{?-?} &
+\cross{MLO}{-?} &
+\cross{MLO}{?=?} &
+\cross{MLO}{?\^{}?} \\
+\cross{MLO}{?\~{}=?} &&&
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{MLO}{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{MLO}{leftUnitary}}
+is true if $1 * x = x$ for all x.
+\item {\bf \cross{MLO}{rightUnitary}}
+is true if $x * 1 = x$ for all x.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ coefficient : (%,NonNegativeInteger) -> R
+ degree : % -> NonNegativeInteger
+ leadingCoefficient : % -> R          
+ minimumDegree : % -> NonNegativeInteger
+ monomial : (R,NonNegativeInteger) -> %
+ reductum : % -> %
+\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
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (Integer,%) -> %
+ ?*? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %       
+ ?**? : (%,NonNegativeInteger) -> %
+ ?^? : (%,NonNegativeInteger) -> %
+\end{verbatim}
+
+These exports come from \refto{BiModule}(R:Ring,R:Ring):
+\begin{verbatim}
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+These exports come from \refto{Algebra}(R:CommutativeRing):
+\begin{verbatim}
+ coerce : R -> % if R has COMRING
+\end{verbatim}
+
+<<category MLO MonogenicLinearOperator>>=
+)abbrev category MLO MonogenicLinearOperator
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains:  NonCommutativeOperatorDivision
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++   This is the category of linear operator rings with one generator.
+++   The generator is not named by the category but can always be
+++   constructed as \spad{monomial(1,1)}.
+++
+++   For convenience, call the generator \spad{G}.
+++   Then each value is equal to
+++       \spad{sum(a(i)*G**i, i = 0..n)}
+++   for some unique \spad{n} and \spad{a(i)} in \spad{R}.
+++
+++   Note that multiplication is not necessarily commutative.
+++   In fact,  if \spad{a} is in \spad{R}, it is quite normal
+++   to have \spad{a*G \^= G*a}.
+
+MonogenicLinearOperator(R): Category == Defn where
+    E ==> NonNegativeInteger
+    R: Ring
+    Defn == Join(Ring, BiModule(R,R)) with
+        if R has CommutativeRing then Algebra(R)
+        degree: $ -> E
+            ++ degree(l) is \spad{n} if
+            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+        minimumDegree: $ -> E
+            ++ 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: ($, E) -> R
+            ++ coefficient(l,k) is \spad{a(k)} if
+            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+        monomial: (R, E) -> $
+            ++ monomial(c,k) produces c times the k-th power of
+            ++ the generating operator, \spad{monomial(1,1)}.
+
+@
+<<MLO.dotabb>>=
+"MLO"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MLO"];
+"MLO" -> "BMODULE"
+"MLO" -> "RING"
+"MLO" -> "ALGEBRA"
+
+@
+<<MLO.dotfull>>=
+"MonogenicLinearOperator(a:Ring)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MLO"];
+"MonogenicLinearOperator(a:Ring)" -> "Ring()"
+"MonogenicLinearOperator(a:Ring)" -> "BiModule(a:Ring,b:Ring)"
+"MonogenicLinearOperator(a:Ring)" -> "Algebra(a:CommutativeRing)"
+
+@
+<<MLO.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"MonogenicLinearOperator(a:Ring)" [color=lightblue];
+"MonogenicLinearOperator(a:Ring)" -> "Ring()"
+"MonogenicLinearOperator(a:Ring)" -> "BiModule(a:Ring,b:Ring)"
+"MonogenicLinearOperator(a:Ring)" -> "Algebra(a:CommutativeRing)"
+
+"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)"
+
+"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)"
+
+"Rng()" [color=lightblue];
+"Rng()" -> "AbelianGroup()"
+"Rng()" -> "SemiGroup()"
+
+"Monoid()" [color=lightblue];
+"Monoid()" -> "SemiGroup()"
+
+"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];
+}
+
+@
 \chapter{Category Layer 13}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FortranMachineTypeCategory}{FMTC}
@@ -39325,6 +40433,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{QuotientFieldCategory}{QFCAT}
 \pagepic{ps/v102quotientfieldcategory.ps}{QFCAT}{0.50}
 
@@ -60546,7 +62445,9 @@ Note that this code is not included in the generated catdef.spad file.
 <<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 MONADWU MonadWithUnit>>
@@ -60592,6 +62493,7 @@ Note that this code is not included in the generated catdef.spad file.
 <<category REAL RealConstant>>
 <<category RETRACT RetractableTo>>
 <<category RING Ring>>
+<<category RMATCAT RectangularMatrixCategory>>
 <<category RMODULE RightModule>>
 <<category RNG Rng>>
 <<category RNS RealNumberSystem>>
@@ -60603,6 +62505,7 @@ Note that this code is not included in the generated catdef.spad file.
 <<category SEXCAT SExpressionCategory>>
 <<category SGROUP SemiGroup>>
 <<category SKAGG StackAggregate>>
+<<category SMATCAT SquareMatrixCategory>>
 <<category SPACEC ThreeSpaceCategory>>
 <<category SPFCAT SpecialFunctionCategory>>
 <<category SRAGG StringAggregate>>
@@ -60732,7 +62635,9 @@ digraph dotabb {
 <<LOGIC.dotabb>>
 <<LSAGG.dotabb>>
 <<LZSTAGG.dotabb>>
+<<MATCAT.dotabb>>
 <<MDAGG.dotabb>>
+<<MLO.dotabb>>
 <<MODULE.dotabb>>
 <<MONAD.dotabb>>
 <<MONADWU.dotabb>>
@@ -60778,6 +62683,7 @@ digraph dotabb {
 <<REAL.dotabb>>
 <<RETRACT.dotabb>>
 <<RING.dotabb>>
+<<RMATCAT.dotabb>>
 <<RMODULE.dotabb>>
 <<RNG.dotabb>>
 <<RNS.dotabb>>
@@ -60789,6 +62695,7 @@ digraph dotabb {
 <<SEXCAT.dotabb>>
 <<SGROUP.dotabb>>
 <<SKAGG.dotabb>>
+<<SMATCAT.dotabb>>
 <<SPACEC.dotabb>>
 <<SPFCAT.dotabb>>
 <<SRAGG.dotabb>>
@@ -60921,7 +62828,9 @@ digraph dotfull {
 <<LOGIC.dotfull>>
 <<LSAGG.dotfull>>
 <<LZSTAGG.dotfull>>
+<<MATCAT.dotfull>>
 <<MDAGG.dotfull>>
+<<MLO.dotfull>>
 <<MODULE.dotfull>>
 <<MONAD.dotfull>>
 <<MONADWU.dotfull>>
@@ -60967,6 +62876,7 @@ digraph dotfull {
 <<REAL.dotfull>>
 <<RETRACT.dotfull>>
 <<RING.dotfull>>
+<<RMATCAT.dotfull>>
 <<RMODULE.dotfull>>
 <<RNG.dotfull>>
 <<RNS.dotfull>>
@@ -60978,6 +62888,7 @@ digraph dotfull {
 <<SEXCAT.dotfull>>
 <<SGROUP.dotfull>>
 <<SKAGG.dotfull>>
+<<SMATCAT.dotfull>>
 <<SPACEC.dotfull>>
 <<SPFCAT.dotfull>>
 <<SRAGG.dotfull>>
diff --git a/books/ps/v102matrixcategory.ps b/books/ps/v102matrixcategory.ps
new file mode 100644
index 0000000..e21e55a
--- /dev/null
+++ b/books/ps/v102matrixcategory.ps
@@ -0,0 +1,743 @@
+%!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 598 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 598 512
+%%PageOrientation: Portrait
+gsave
+36 36 562 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
+560 474 lineto
+560 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+560 474 lineto
+560 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 508 468 moveto
+46 468 lineto
+46 432 lineto
+508 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 508 468 moveto
+46 468 lineto
+46 432 lineto
+508 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+54 445 moveto
+(MatrixCategory\(a:Ring,b:FiniteLinearAggregate\(a\),c:FiniteLinearAggregate\(a\))
+[12.48 6.24 3.84 5.04 3.84 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 3.84 6.96 6.96 3.6 6.96 3.84 7.44 3.84 6.96 3.84 3.84 6.24 8.64 3.84 6.96 6.24 6.24 4.8 9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 6.24 4.56 3.6 6.24 3.84 7.44 3.84 6.96 3.84 3.84 6.24 8.64 3.84 6.96 6.24 6.24 4.8 9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 6.24 4.56]
+xshow
+end grestore
+end grestore
+% TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 554 396 moveto
+0 396 lineto
+0 360 lineto
+554 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 554 396 moveto
+0 396 lineto
+0 360 lineto
+554 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 373 moveto
+(TwoDimensionalArrayCategory\(a:Type,b:FiniteLinearAggregate\(a\),c:FiniteLinearAggregate\(a\)\))
+[7.2 9.6 6.96 10.08 3.84 10.8 6.24 6.96 5.52 3.84 6.96 6.96 6.24 3.84 10.08 5.28 4.8 5.76 6.96 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 3.6 6.96 3.84 7.44 3.84 6.96 3.84 3.84 6.24 8.64 3.84 6.96 6.24 6.24 4.8 9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 6.24 4.56 3.6 6.24 3.84 7.44 3.84 6.96 3.84 3.84 6.24 8.64 3.84 6.96 6.24 6.24 4.8 9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% MatrixCategory(a:Ring,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a)->TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))
+newpath 277 432 moveto
+277 424 277 415 277 406 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 281 406 moveto
+277 396 lineto
+274 406 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 281 406 moveto
+277 396 lineto
+274 406 lineto
+closepath
+stroke
+end grestore
+% HomogeneousAggregate(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 378 324 moveto
+176 324 lineto
+176 288 lineto
+378 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 378 324 moveto
+176 324 lineto
+176 288 lineto
+378 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+183 301 moveto
+(HomogeneousAggregate\(a:Type\))
+[10.08 6.96 10.8 6.96 6.72 6.24 6.96 6.24 6.96 6.96 5.52 9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))->HomogeneousAggregate(a:Type)
+newpath 277 360 moveto
+277 352 277 343 277 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 281 334 moveto
+277 324 lineto
+274 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 281 334 moveto
+277 324 lineto
+274 334 lineto
+closepath
+stroke
+end grestore
+% Aggregate()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 203 252 moveto
+119 252 lineto
+119 216 lineto
+203 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 203 252 moveto
+119 252 lineto
+119 216 lineto
+203 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+126 229 moveto
+(Aggregate\(\))
+[9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% HomogeneousAggregate(a:Type)->Aggregate()
+newpath 248 288 moveto
+233 279 214 268 199 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 255 moveto
+190 252 lineto
+196 260 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 255 moveto
+190 252 lineto
+196 260 lineto
+closepath
+stroke
+end grestore
+% Evalable(a:Type)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 333 252 moveto
+221 252 lineto
+221 216 lineto
+333 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 333 252 moveto
+221 252 lineto
+221 216 lineto
+333 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+229 229 moveto
+(Evalable\(a:Type\))
+[8.64 6.72 6.24 3.84 6.24 6.96 3.84 6.24 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% HomogeneousAggregate(a:Type)->Evalable(a:Type)
+newpath 277 288 moveto
+277 280 277 271 277 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 281 262 moveto
+277 252 lineto
+274 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 281 262 moveto
+277 252 lineto
+274 262 lineto
+closepath
+stroke
+end grestore
+% SetCategory()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 445 252 moveto
+351 252 lineto
+351 216 lineto
+445 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 445 252 moveto
+351 252 lineto
+351 216 lineto
+445 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+358 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
+% HomogeneousAggregate(a:Type)->SetCategory()
+newpath 308 288 moveto
+323 279 342 267 359 257 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 361 260 moveto
+368 252 lineto
+358 254 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 361 260 moveto
+368 252 lineto
+358 254 lineto
+closepath
+stroke
+end grestore
+% Type()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 218 108 moveto
+164 108 lineto
+164 72 lineto
+218 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 218 108 moveto
+164 108 lineto
+164 72 lineto
+218 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+172 85 moveto
+(Type\(\))
+[7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Aggregate()->Type()
+newpath 165 216 moveto
+170 191 180 147 185 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 188 118 moveto
+187 108 lineto
+182 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 188 118 moveto
+187 108 lineto
+182 117 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 298 180 moveto
+214 180 lineto
+214 144 lineto
+298 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 298 180 moveto
+214 180 lineto
+214 144 lineto
+298 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+221 157 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 362 216 moveto
+343 206 320 195 300 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 301 182 moveto
+291 180 lineto
+298 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 301 182 moveto
+291 180 lineto
+298 188 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 480 180 moveto
+316 180 lineto
+316 144 lineto
+480 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 480 180 moveto
+316 180 lineto
+316 144 lineto
+480 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+324 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 398 216 moveto
+398 208 398 199 398 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 402 190 moveto
+398 180 lineto
+395 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 402 190 moveto
+398 180 lineto
+395 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 290 36 moveto
+222 36 lineto
+222 0 lineto
+290 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 290 36 moveto
+222 36 lineto
+222 0 lineto
+290 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+230 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 256 144 moveto
+256 119 256 75 256 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 260 46 moveto
+256 36 lineto
+253 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 260 46 moveto
+256 36 lineto
+253 46 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 440 108 moveto
+308 108 lineto
+308 72 lineto
+440 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 440 108 moveto
+308 108 lineto
+308 72 lineto
+440 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+316 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 392 144 moveto
+389 136 386 126 383 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 386 117 moveto
+380 108 lineto
+380 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 386 117 moveto
+380 108 lineto
+380 119 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 344 72 moveto
+329 63 310 51 294 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 295 38 moveto
+285 36 lineto
+292 44 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 295 38 moveto
+285 36 lineto
+292 44 lineto
+closepath
+stroke
+end grestore
+% Type()->Category
+newpath 207 72 moveto
+215 63 224 53 233 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 236 46 moveto
+240 36 lineto
+231 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 236 46 moveto
+240 36 lineto
+231 41 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102monogeniclinearoperator.ps b/books/ps/v102monogeniclinearoperator.ps
new file mode 100644
index 0000000..33b9373
--- /dev/null
+++ b/books/ps/v102monogeniclinearoperator.ps
@@ -0,0 +1,1150 @@
+%!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 679 656
+%%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 679 656
+%%PageOrientation: Portrait
+gsave
+36 36 643 620 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 618 lineto
+641 618 lineto
+641 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 618 lineto
+641 618 lineto
+641 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% MonogenicLinearOperator(a:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 349 612 moveto
+135 612 lineto
+135 576 lineto
+349 576 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 349 612 moveto
+135 612 lineto
+135 576 lineto
+349 576 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+143 589 moveto
+(MonogenicLinearOperator\(a:Ring\))
+[12.48 6.96 6.96 6.96 6.72 6.24 6.96 3.84 6.24 8.64 3.84 6.96 6.24 6.24 4.8 10.08 6.96 6.24 4.8 6.24 3.84 6.96 4.8 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% Ring()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 405 468 moveto
+351 468 lineto
+351 432 lineto
+405 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 405 468 moveto
+351 468 lineto
+351 432 lineto
+405 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+359 445 moveto
+(Ring\(\))
+[9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% MonogenicLinearOperator(a:Ring)->Ring()
+newpath 292 576 moveto
+310 567 329 556 343 540 curveto
+358 522 367 497 372 478 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 375 479 moveto
+375 468 lineto
+369 477 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 375 479 moveto
+375 468 lineto
+369 477 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 273 324 moveto
+111 324 lineto
+111 288 lineto
+273 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 273 324 moveto
+111 324 lineto
+111 288 lineto
+273 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+119 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
+% MonogenicLinearOperator(a:Ring)->BiModule(a:Ring,b:Ring)
+newpath 200 576 moveto
+181 567 159 554 141 540 curveto
+80 487 56 472 29 396 curveto
+24 380 20 372 29 360 curveto
+39 347 69 335 101 327 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 102 330 moveto
+111 324 lineto
+100 324 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 102 330 moveto
+111 324 lineto
+100 324 lineto
+closepath
+stroke
+end grestore
+% Algebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 334 540 moveto
+150 540 lineto
+150 504 lineto
+334 504 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 334 540 moveto
+150 540 lineto
+150 504 lineto
+334 504 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+158 517 moveto
+(Algebra\(a:CommutativeRing\))
+[10.08 3.84 6.72 6.24 6.96 4.8 6.24 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
+% MonogenicLinearOperator(a:Ring)->Algebra(a:CommutativeRing)
+newpath 242 576 moveto
+242 568 242 559 242 550 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 246 550 moveto
+242 540 lineto
+239 550 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 246 550 moveto
+242 540 lineto
+239 550 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 460 396 moveto
+406 396 lineto
+406 360 lineto
+460 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 460 396 moveto
+406 396 lineto
+406 360 lineto
+460 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+416 373 moveto
+(Rng\(\))
+[9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Rng()
+newpath 392 432 moveto
+398 424 406 413 413 404 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 416 406 moveto
+419 396 lineto
+410 402 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 416 406 moveto
+419 396 lineto
+410 402 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 548 396 moveto
+478 396 lineto
+478 360 lineto
+548 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 548 396 moveto
+478 396 lineto
+478 360 lineto
+548 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+485 373 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 405 435 moveto
+423 425 449 412 470 401 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 472 404 moveto
+479 396 lineto
+469 398 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 472 404 moveto
+479 396 lineto
+469 398 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 406 252 moveto
+276 252 lineto
+276 216 lineto
+406 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 406 252 moveto
+276 252 lineto
+276 216 lineto
+406 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+284 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
+% Ring()->LeftModule(a:Ring)
+newpath 375 432 moveto
+369 394 353 307 346 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 349 261 moveto
+344 252 lineto
+343 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 349 261 moveto
+344 252 lineto
+343 262 lineto
+closepath
+stroke
+end grestore
+% BiModule(a:Ring,b:Ring)->LeftModule(a:Ring)
+newpath 230 288 moveto
+250 278 274 267 295 256 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 296 259 moveto
+304 252 lineto
+293 253 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 296 259 moveto
+304 252 lineto
+293 253 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 258 252 moveto
+122 252 lineto
+122 216 lineto
+258 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 258 252 moveto
+122 252 lineto
+122 216 lineto
+258 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+129 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 191 288 moveto
+191 280 191 271 191 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 194 262 moveto
+190 252 lineto
+188 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 194 262 moveto
+190 252 lineto
+188 262 lineto
+closepath
+stroke
+end grestore
+% Algebra(a:CommutativeRing)->Ring()
+newpath 276 504 moveto
+296 494 321 480 342 470 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 344 473 moveto
+351 465 lineto
+341 467 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 344 473 moveto
+351 465 lineto
+341 467 lineto
+closepath
+stroke
+end grestore
+% Module(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 301 468 moveto
+119 468 lineto
+119 432 lineto
+301 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 301 468 moveto
+119 468 lineto
+119 432 lineto
+301 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+126 445 moveto
+(Module\(a:CommutativeRing\))
+[12.48 6.96 6.96 6.96 3.84 6.24 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(a:CommutativeRing)->Module(a:CommutativeRing)
+newpath 234 504 moveto
+230 496 226 486 222 477 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 225 476 moveto
+218 468 lineto
+219 479 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 225 476 moveto
+218 468 lineto
+219 479 lineto
+closepath
+stroke
+end grestore
+% BiModule(a:CommutativeRing,b:CommutativeRing)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 350 396 moveto
+38 396 lineto
+38 360 lineto
+350 360 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 350 396 moveto
+38 396 lineto
+38 360 lineto
+350 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+45 373 moveto
+(BiModule\(a:CommutativeRing,b:CommutativeRing\))
+[9.36 3.84 12.48 6.96 6.96 6.96 3.84 6.24 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 3.6 6.96 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
+% Module(a:CommutativeRing)->BiModule(a:CommutativeRing,b:CommutativeRing)
+newpath 206 432 moveto
+204 424 202 415 200 406 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 203 405 moveto
+198 396 lineto
+197 406 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 203 405 moveto
+198 396 lineto
+197 406 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 394 108 moveto
+288 108 lineto
+288 72 lineto
+394 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 394 108 moveto
+288 108 lineto
+288 72 lineto
+394 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+296 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 436 360 moveto
+442 318 452 215 413 144 curveto
+406 132 396 122 385 114 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 387 111 moveto
+377 108 lineto
+383 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 387 111 moveto
+377 108 lineto
+383 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 555 324 moveto
+465 324 lineto
+465 288 lineto
+555 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 555 324 moveto
+465 324 lineto
+465 288 lineto
+555 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+473 301 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 452 360 moveto
+462 351 473 341 483 331 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 486 333 moveto
+491 324 lineto
+481 328 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 486 333 moveto
+491 324 lineto
+481 328 lineto
+closepath
+stroke
+end grestore
+% Monoid()->SemiGroup()
+newpath 512 360 moveto
+511 352 511 343 511 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 515 334 moveto
+511 324 lineto
+508 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 515 334 moveto
+511 324 lineto
+508 334 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 404 180 moveto
+278 180 lineto
+278 144 lineto
+404 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 404 180 moveto
+278 180 lineto
+278 144 lineto
+404 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+286 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 341 216 moveto
+341 208 341 199 341 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 345 190 moveto
+341 180 lineto
+338 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 345 190 moveto
+341 180 lineto
+338 190 lineto
+closepath
+stroke
+end grestore
+% BiModule(a:CommutativeRing,b:CommutativeRing)->BiModule(a:Ring,b:Ring)
+newpath 193 360 moveto
+193 352 193 343 193 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 196 334 moveto
+192 324 lineto
+190 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 196 334 moveto
+192 324 lineto
+190 334 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 259 180 moveto
+125 180 lineto
+125 144 lineto
+259 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 259 180 moveto
+125 180 lineto
+125 144 lineto
+259 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+133 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 191 216 moveto
+191 208 191 199 191 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 194 190 moveto
+192 180 lineto
+188 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 194 190 moveto
+192 180 lineto
+188 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 336 36 moveto
+248 36 lineto
+248 0 lineto
+336 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 336 36 moveto
+248 36 lineto
+248 0 lineto
+336 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+256 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 329 72 moveto
+323 64 316 54 310 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 313 42 moveto
+304 36 lineto
+307 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 313 42 moveto
+304 36 lineto
+307 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 426 36 moveto
+354 36 lineto
+354 0 lineto
+426 0 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 426 36 moveto
+354 36 lineto
+354 0 lineto
+426 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+361 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 353 72 moveto
+359 64 366 54 372 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 375 46 moveto
+378 36 lineto
+369 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 375 46 moveto
+378 36 lineto
+369 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 635 252 moveto
+557 252 lineto
+557 216 lineto
+635 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 635 252 moveto
+557 252 lineto
+557 216 lineto
+635 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+565 229 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 532 288 moveto
+543 279 556 268 567 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 569 261 moveto
+575 252 lineto
+565 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 569 261 moveto
+575 252 lineto
+565 255 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 539 252 moveto
+469 252 lineto
+469 216 lineto
+539 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 539 252 moveto
+469 252 lineto
+469 216 lineto
+539 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+476 229 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 508 288 moveto
+507 280 507 271 506 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 510 262 moveto
+506 252 lineto
+503 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 510 262 moveto
+506 252 lineto
+503 262 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->AbelianGroup()
+newpath 230 144 moveto
+250 134 274 123 295 112 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 296 115 moveto
+304 108 lineto
+293 109 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 296 115 moveto
+304 108 lineto
+293 109 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->AbelianGroup()
+newpath 341 144 moveto
+341 136 341 127 341 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 345 118 moveto
+341 108 lineto
+338 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 345 118 moveto
+341 108 lineto
+338 118 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102rectangularmatrixcategory.ps b/books/ps/v102rectangularmatrixcategory.ps
new file mode 100644
index 0000000..8fe9b23
--- /dev/null
+++ b/books/ps/v102rectangularmatrixcategory.ps
@@ -0,0 +1,585 @@
+%!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 856 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 856 368
+%%PageOrientation: Portrait
+gsave
+36 36 820 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
+818 330 lineto
+818 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+818 330 lineto
+818 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 812 324 moveto
+0 324 lineto
+0 288 lineto
+812 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 812 324 moveto
+0 324 lineto
+0 288 lineto
+812 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 301 moveto
+(RectangularMatrixCategory\(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory\(b,c\),e:DirectProductCategory\(a,c\)\))
+[9.12 6.24 6.24 4.08 6.24 6.96 6.96 6.96 3.84 6.24 4.8 12.48 6.24 3.84 5.04 3.84 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.84 6.96 6.96 9.84 6.24 6.72 6.24 3.84 3.84 6.48 6.24 4.56 6.96 3.84 6.24 6.72 6.24 4.32 3.6 6.96 3.84 9.84 6.96 6.96 9.84 6.24 6.72 6.24 3.84 3.84 6.48 6.24 4.56 6.96 3.84 6.24 6.72 6.24 4.32 3.6 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.96 3.6 6.24 4.56 3.6 6.24 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 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.24 4.56 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 419 252 moveto
+257 252 lineto
+257 216 lineto
+419 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 419 252 moveto
+257 252 lineto
+257 216 lineto
+419 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+265 229 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
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))->BiModule(a:Ring,b:Ring)
+newpath 389 288 moveto
+381 279 371 269 362 260 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 364 257 moveto
+355 252 lineto
+359 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 364 257 moveto
+355 252 lineto
+359 262 lineto
+closepath
+stroke
+end grestore
+% HOAGG...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 513 252 moveto
+437 252 lineto
+437 216 lineto
+513 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 513 252 moveto
+437 252 lineto
+437 216 lineto
+513 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+444 229 moveto
+(HOAGG...)
+[10.08 9.36 9.36 10.08 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))->HOAGG...
+newpath 423 288 moveto
+432 279 442 269 451 259 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 453 262 moveto
+458 252 lineto
+448 257 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 453 262 moveto
+458 252 lineto
+448 257 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 328 180 moveto
+198 180 lineto
+198 144 lineto
+328 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 328 180 moveto
+198 180 lineto
+198 144 lineto
+328 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+206 157 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 319 216 moveto
+310 207 299 197 289 187 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 292 185 moveto
+282 180 lineto
+287 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 292 185 moveto
+282 180 lineto
+287 190 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 482 180 moveto
+346 180 lineto
+346 144 lineto
+482 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 482 180 moveto
+346 180 lineto
+346 144 lineto
+482 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+353 157 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 357 216 moveto
+367 207 378 197 388 187 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 390 190 moveto
+395 180 lineto
+385 185 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 390 190 moveto
+395 180 lineto
+385 185 lineto
+closepath
+stroke
+end grestore
+% ABELGRP...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 383 36 moveto
+293 36 lineto
+293 0 lineto
+383 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 383 36 moveto
+293 36 lineto
+293 0 lineto
+383 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+300 13 moveto
+(ABELGRP...)
+[10.08 9.36 8.64 8.64 10.08 9.36 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+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 327 108 moveto
+201 108 lineto
+201 72 lineto
+327 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 327 108 moveto
+201 108 lineto
+201 72 lineto
+327 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+209 85 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 263 144 moveto
+264 136 264 127 264 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 268 118 moveto
+264 108 lineto
+261 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 268 118 moveto
+264 108 lineto
+261 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 480 108 moveto
+346 108 lineto
+346 72 lineto
+480 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 480 108 moveto
+346 108 lineto
+346 72 lineto
+480 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+354 85 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 414 144 moveto
+413 136 413 127 413 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 417 118 moveto
+413 108 lineto
+410 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 417 118 moveto
+413 108 lineto
+410 118 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->ABELGRP...
+newpath 394 72 moveto
+385 63 374 53 364 43 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 367 41 moveto
+357 36 lineto
+362 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 367 41 moveto
+357 36 lineto
+362 46 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->ABELGRP...
+newpath 283 72 moveto
+292 63 303 53 313 43 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 315 46 moveto
+320 36 lineto
+310 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 315 46 moveto
+320 36 lineto
+310 41 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102squarematrixcategory.ps b/books/ps/v102squarematrixcategory.ps
new file mode 100644
index 0000000..a254629
--- /dev/null
+++ b/books/ps/v102squarematrixcategory.ps
@@ -0,0 +1,1269 @@
+%!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 1331 584
+%%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 1331 584
+%%PageOrientation: Portrait
+gsave
+36 36 1295 548 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 546 lineto
+1293 546 lineto
+1293 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 546 lineto
+1293 546 lineto
+1293 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 1287 540 moveto
+633 540 lineto
+633 504 lineto
+1287 504 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1287 540 moveto
+633 540 lineto
+633 504 lineto
+1287 504 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+641 517 moveto
+(SquareMatrixCategory\(a:NonNegativeInteger,b:Ring,c:DirectProductCategory\(a,b\),d:DirectProductCategory\(a,b\))
+[7.68 6.72 6.96 6.24 4.8 6.24 12.48 6.24 3.84 5.04 3.84 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.84 6.96 6.96 9.84 6.24 6.72 6.24 3.84 3.84 6.48 6.24 4.56 6.96 3.84 6.24 6.72 6.24 4.32 3.6 6.96 3.84 9.36 3.84 6.96 6.96 3.6 6.24 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 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 4.56 3.6 6.96 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 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 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 801 396 moveto
+639 396 lineto
+639 360 lineto
+801 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 801 396 moveto
+639 396 lineto
+639 360 lineto
+801 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+647 373 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
+% SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)->BiModule(a:Ring,b:Ring)
+newpath 921 504 moveto
+902 494 878 482 859 468 curveto
+840 454 839 445 821 432 curveto
+805 420 786 410 769 401 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 770 398 moveto
+760 396 lineto
+767 404 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 770 398 moveto
+760 396 lineto
+767 404 lineto
+closepath
+stroke
+end grestore
+% DifferentialExtension(a:Ring)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 1052 468 moveto
+868 468 lineto
+868 432 lineto
+1052 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1052 468 moveto
+868 468 lineto
+868 432 lineto
+1052 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+876 445 moveto
+(DifferentialExtension\(a:Ring\))
+[10.08 3.84 4.56 4.08 6.24 4.8 6.24 6.96 3.84 3.84 6.24 3.84 8.64 6.96 3.84 6.24 6.96 5.52 3.84 6.96 6.96 4.56 6.24 3.84 9.36 3.84 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)->DifferentialExtension(a:Ring)
+newpath 960 504 moveto
+960 496 960 487 960 478 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 964 478 moveto
+960 468 lineto
+957 478 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 964 478 moveto
+960 468 lineto
+957 478 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 1152 468 moveto
+1070 468 lineto
+1070 432 lineto
+1152 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1152 468 moveto
+1070 468 lineto
+1070 432 lineto
+1152 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1077 445 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
+% SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)->FLINEXP...
+newpath 998 504 moveto
+1018 494 1043 483 1064 473 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1066 476 moveto
+1073 468 lineto
+1063 470 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1066 476 moveto
+1073 468 lineto
+1063 470 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 1256 468 moveto
+1170 468 lineto
+1170 432 lineto
+1256 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1256 468 moveto
+1170 468 lineto
+1170 432 lineto
+1256 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1177 445 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
+% SquareMatrixCategory(a:NonNegativeInteger,b:Ring,c:DirectProductCategory(a,b),d:DirectProductCategory(a,b)->FRETRCT...
+newpath 1032 504 moveto
+1068 495 1112 483 1160 468 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1161 471 moveto
+1170 465 lineto
+1159 465 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1161 471 moveto
+1170 465 lineto
+1159 465 lineto
+closepath
+stroke
+end grestore
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 812 468 moveto
+0 468 lineto
+0 432 lineto
+812 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 812 468 moveto
+0 468 lineto
+0 432 lineto
+812 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 445 moveto
+(RectangularMatrixCategory\(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory\(b,c\),e:DirectProductCategory\(a,c\)\))
+[9.12 6.24 6.24 4.08 6.24 6.96 6.96 6.96 3.84 6.24 4.8 12.48 6.24 3.84 5.04 3.84 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.84 6.96 6.96 9.84 6.24 6.72 6.24 3.84 3.84 6.48 6.24 4.56 6.96 3.84 6.24 6.72 6.24 4.32 3.6 6.96 3.84 9.84 6.96 6.96 9.84 6.24 6.72 6.24 3.84 3.84 6.48 6.24 4.56 6.96 3.84 6.24 6.72 6.24 4.32 3.6 6.24 3.84 9.36 3.84 6.96 6.96 3.6 6.96 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.96 3.6 6.24 4.56 3.6 6.24 3.84 10.08 3.84 4.8 6.24 6.24 3.84 7.68 4.8 6.96 6.96 6.96 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.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% 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))
+newpath 821 504 moveto
+739 493 636 480 554 469 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 554 466 moveto
+544 468 lineto
+554 472 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 554 466 moveto
+544 468 lineto
+554 472 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 892 180 moveto
+762 180 lineto
+762 144 lineto
+892 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 892 180 moveto
+762 180 lineto
+762 144 lineto
+892 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+770 157 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 739 360 moveto
+749 350 760 337 768 324 curveto
+794 281 811 224 820 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 823 191 moveto
+823 180 lineto
+817 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 823 191 moveto
+823 180 lineto
+817 189 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 759 324 moveto
+623 324 lineto
+623 288 lineto
+759 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 759 324 moveto
+623 324 lineto
+623 288 lineto
+759 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+630 301 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 713 360 moveto
+709 352 706 342 702 333 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 705 332 moveto
+698 324 lineto
+699 335 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 705 332 moveto
+698 324 lineto
+699 335 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 987 252 moveto
+933 252 lineto
+933 216 lineto
+987 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 987 252 moveto
+933 252 lineto
+933 216 lineto
+987 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+941 229 moveto
+(Ring\(\))
+[9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% DifferentialExtension(a:Ring)->Ring()
+newpath 946 432 moveto
+930 408 902 365 892 324 curveto
+888 308 885 302 892 288 curveto
+899 273 912 262 925 253 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 927 256 moveto
+933 247 lineto
+923 250 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 927 256 moveto
+933 247 lineto
+923 250 lineto
+closepath
+stroke
+end grestore
+% DifferentialRing()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 1019 324 moveto
+901 324 lineto
+901 288 lineto
+1019 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1019 324 moveto
+901 324 lineto
+901 288 lineto
+1019 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+909 301 moveto
+(DifferentialRing\(\))
+[10.08 3.84 4.56 4.08 6.24 4.8 6.24 6.96 3.84 3.84 6.24 3.84 9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% DifferentialExtension(a:Ring)->DifferentialRing()
+newpath 960 432 moveto
+960 407 960 363 960 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 964 334 moveto
+960 324 lineto
+957 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 964 334 moveto
+960 324 lineto
+957 334 lineto
+closepath
+stroke
+end grestore
+% PartialDifferentialRing(Symbol)
+[ /Rect [ 1022 360 1220 396 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=PDRING) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 1220 396 moveto
+1022 396 lineto
+1022 360 lineto
+1220 360 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 1220 396 moveto
+1022 396 lineto
+1022 360 lineto
+1220 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1030 373 moveto
+(PartialDifferentialRing\(Symbol\))
+[7.44 6.24 5.04 3.84 3.84 6.24 3.84 10.08 3.84 4.56 4.08 6.24 4.8 6.24 6.96 3.84 3.84 6.24 3.84 9.36 3.84 6.96 6.96 4.56 7.68 6.96 10.8 6.96 6.96 3.84 4.56]
+xshow
+end grestore
+end grestore
+% DifferentialExtension(a:Ring)->PartialDifferentialRing(Symbol)
+newpath 1001 432 moveto
+1022 422 1049 410 1072 400 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1073 403 moveto
+1081 396 lineto
+1070 397 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1073 403 moveto
+1081 396 lineto
+1070 397 lineto
+closepath
+stroke
+end grestore
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))->BiModule(a:Ring,b:Ring)
+newpath 485 432 moveto
+530 422 586 409 632 398 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 633 401 moveto
+642 396 lineto
+632 395 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 633 401 moveto
+642 396 lineto
+632 395 lineto
+closepath
+stroke
+end grestore
+% HOAGG...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 444 396 moveto
+368 396 lineto
+368 360 lineto
+444 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 444 396 moveto
+368 396 lineto
+368 360 lineto
+444 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+375 373 moveto
+(HOAGG...)
+[10.08 9.36 9.36 10.08 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% RectangularMatrixCategory(a:NonNegativeInteger,b:NonNegativeInteger,c:Ring,d:DirectProductCategory(b,c),e:DirectProductCategory(a,c))->HOAGG...
+newpath 406 432 moveto
+406 424 406 415 406 406 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 410 406 moveto
+406 396 lineto
+403 406 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 410 406 moveto
+406 396 lineto
+403 406 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 987 180 moveto
+933 180 lineto
+933 144 lineto
+987 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 987 180 moveto
+933 180 lineto
+933 144 lineto
+987 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+943 157 moveto
+(Rng\(\))
+[9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Ring()->Rng()
+newpath 960 216 moveto
+960 208 960 199 960 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 964 190 moveto
+960 180 lineto
+957 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 964 190 moveto
+960 180 lineto
+957 190 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 1075 180 moveto
+1005 180 lineto
+1005 144 lineto
+1075 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1075 180 moveto
+1005 180 lineto
+1005 144 lineto
+1075 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1012 157 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 980 216 moveto
+990 207 1002 196 1013 187 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1015 190 moveto
+1020 180 lineto
+1010 185 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1015 190 moveto
+1020 180 lineto
+1010 185 lineto
+closepath
+stroke
+end grestore
+% Ring()->LeftModule(a:Ring)
+newpath 933 219 moveto
+915 209 890 196 870 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 871 182 moveto
+861 180 lineto
+868 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 871 182 moveto
+861 180 lineto
+868 188 lineto
+closepath
+stroke
+end grestore
+% DifferentialRing()->Ring()
+newpath 960 288 moveto
+960 280 960 271 960 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 964 262 moveto
+960 252 lineto
+957 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 964 262 moveto
+960 252 lineto
+957 262 lineto
+closepath
+stroke
+end grestore
+% PartialDifferentialRing(a:SetCategory)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 1271 324 moveto
+1037 324 lineto
+1037 288 lineto
+1271 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1271 324 moveto
+1037 324 lineto
+1037 288 lineto
+1271 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1045 301 moveto
+(PartialDifferentialRing\(a:SetCategory\))
+[7.44 6.24 5.04 3.84 3.84 6.24 3.84 10.08 3.84 4.56 4.08 6.24 4.8 6.24 6.96 3.84 3.84 6.24 3.84 9.36 3.84 6.96 6.96 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.96 4.56]
+xshow
+end grestore
+end grestore
+% PartialDifferentialRing(Symbol)->PartialDifferentialRing(a:SetCategory)
+newpath 1129 360 moveto
+1133 352 1137 342 1142 333 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1145 335 moveto
+1146 324 lineto
+1139 332 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1145 335 moveto
+1146 324 lineto
+1139 332 lineto
+closepath
+stroke
+end grestore
+% PartialDifferentialRing(a:SetCategory)->Ring()
+newpath 1105 288 moveto
+1072 275 1028 259 997 248 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 998 244 moveto
+987 244 lineto
+995 251 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 998 244 moveto
+987 244 lineto
+995 251 lineto
+closepath
+stroke
+end grestore
+% ABELGRP...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 917 36 moveto
+827 36 lineto
+827 0 lineto
+917 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 917 36 moveto
+827 36 lineto
+827 0 lineto
+917 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+834 13 moveto
+(ABELGRP...)
+[10.08 9.36 8.64 8.64 10.08 9.36 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Rng()->ABELGRP...
+newpath 960 144 moveto
+960 125 957 94 944 72 curveto
+937 60 926 50 915 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 917 39 moveto
+907 36 lineto
+913 45 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 917 39 moveto
+907 36 lineto
+913 45 lineto
+closepath
+stroke
+end grestore
+% SGROUP...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 1074 108 moveto
+994 108 lineto
+994 72 lineto
+1074 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 1074 108 moveto
+994 108 lineto
+994 72 lineto
+1074 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+1002 85 moveto
+(SGROUP...)
+[7.68 10.08 8.64 10.08 10.08 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Rng()->SGROUP...
+newpath 979 144 moveto
+988 135 999 125 1009 115 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1011 118 moveto
+1016 108 lineto
+1006 113 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1011 118 moveto
+1016 108 lineto
+1006 113 lineto
+closepath
+stroke
+end grestore
+% Monoid()->SGROUP...
+newpath 1038 144 moveto
+1037 136 1037 127 1036 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 1040 118 moveto
+1036 108 lineto
+1033 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 1040 118 moveto
+1036 108 lineto
+1033 118 lineto
+closepath
+stroke
+end grestore
+% LMODULE...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 791 108 moveto
+695 108 lineto
+695 72 lineto
+791 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 791 108 moveto
+695 108 lineto
+695 72 lineto
+791 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+703 85 moveto
+(LMODULE...)
+[8.64 12.48 10.08 10.08 10.08 8.64 8.64 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% LeftModule(a:Ring)->LMODULE...
+newpath 806 144 moveto
+796 135 783 124 772 115 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 774 112 moveto
+764 108 lineto
+769 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 774 112 moveto
+764 108 lineto
+769 117 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 935 108 moveto
+809 108 lineto
+809 72 lineto
+935 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 935 108 moveto
+809 108 lineto
+809 72 lineto
+935 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+817 85 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 838 144 moveto
+843 136 850 126 856 116 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 859 118 moveto
+861 108 lineto
+853 115 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 859 118 moveto
+861 108 lineto
+853 115 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 742 252 moveto
+608 252 lineto
+608 216 lineto
+742 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 742 252 moveto
+608 252 lineto
+608 216 lineto
+742 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+616 229 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 687 288 moveto
+685 280 683 271 681 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 684 261 moveto
+679 252 lineto
+678 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 684 261 moveto
+679 252 lineto
+678 262 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->ABELGRP...
+newpath 670 216 moveto
+662 183 652 114 686 72 curveto
+702 51 768 36 817 27 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 818 30 moveto
+827 25 lineto
+817 24 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 818 30 moveto
+827 25 lineto
+817 24 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->ABELGRP...
+newpath 872 72 moveto
+872 64 872 55 872 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 876 46 moveto
+872 36 lineto
+869 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 876 46 moveto
+872 36 lineto
+869 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/changelog b/changelog
index 028545d..1f920ab 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,10 @@
+20081101 tpd books/bookvol10.2 merge categories
+20081101 tpd books/ps/v102squarematrixcategory.ps added
+20081101 tpd books/ps/v102rectangularmatrixcategory.ps added
+20081101 tpd src/algebra/matcat.spad merge with bookvol10.2
+20081101 tpd books/ps/v102matrixcategory.ps added
+20081101 tpd books/ps/v102monogeniclinearoperator.ps added
+20081101 tpd src/algebra/lodop.spad move categories to bookvol10.2
 20081029 tpd books/bookvol10.2.pamphlet add categories
 20081029 tpd books/ps/v102polynomialsetcategory.ps corrected
 20081029 tpd src/algebra/triset.spad move categories to bookvol10.2
diff --git a/src/algebra/lodop.spad.pamphlet b/src/algebra/lodop.spad.pamphlet
index f1e5eeb..37d3567 100644
--- a/src/algebra/lodop.spad.pamphlet
+++ b/src/algebra/lodop.spad.pamphlet
@@ -9,59 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category MLO MonogenicLinearOperator}
-<<category MLO MonogenicLinearOperator>>=
-)abbrev category MLO MonogenicLinearOperator
-++ Author: Stephen M. Watt
-++ Date Created: 1986
-++ Date Last Updated: May 30, 1991
-++ Basic Operations:
-++ Related Domains:  NonCommutativeOperatorDivision
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ Examples:
-++ References:
-++ Description:
-++   This is the category of linear operator rings with one generator.
-++   The generator is not named by the category but can always be
-++   constructed as \spad{monomial(1,1)}.
-++
-++   For convenience, call the generator \spad{G}.
-++   Then each value is equal to
-++       \spad{sum(a(i)*G**i, i = 0..n)}
-++   for some unique \spad{n} and \spad{a(i)} in \spad{R}.
-++
-++   Note that multiplication is not necessarily commutative.
-++   In fact,  if \spad{a} is in \spad{R}, it is quite normal
-++   to have \spad{a*G \^= G*a}.
-
-MonogenicLinearOperator(R): Category == Defn where
-    E ==> NonNegativeInteger
-    R: Ring
-    Defn == Join(Ring, BiModule(R,R)) with
-        if R has CommutativeRing then Algebra(R)
-        degree: $ -> E
-            ++ degree(l) is \spad{n} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        minimumDegree: $ -> E
-            ++ 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: ($, E) -> R
-            ++ coefficient(l,k) is \spad{a(k)} if
-            ++   \spad{l = sum(monomial(a(i),i), i = 0..n)}.
-        monomial: (R, E) -> $
-            ++ monomial(c,k) produces c times the k-th power of
-            ++ the generating operator, \spad{monomial(1,1)}.
-
-@
 \section{domain OMLO OppositeMonogenicLinearOperator}
 <<domain OMLO OppositeMonogenicLinearOperator>>=
 )abbrev domain OMLO OppositeMonogenicLinearOperator
@@ -335,7 +282,6 @@ DirectProductMatrixModule(n, R, M, S): DPcategory == DPcapsule where
 <<*>>=
 <<license>>
 
-<<category MLO MonogenicLinearOperator>>
 <<domain OMLO OppositeMonogenicLinearOperator>>
 <<package NCODIV NonCommutativeOperatorDivision>>
 <<domain ODR OrdinaryDifferentialRing>>
diff --git a/src/algebra/matcat.spad.pamphlet b/src/algebra/matcat.spad.pamphlet
deleted file mode 100644
index f7bc1ef..0000000
--- a/src/algebra/matcat.spad.pamphlet
+++ /dev/null
@@ -1,904 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra matcat.spad}
-\author{Johannes Grabmeier, Oswald Gschnitzer, Clifton J. Williamson}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{category MATCAT MatrixCategory}
-<<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
-       ++ (i.e. 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)
-
-@
-\section{category RMATCAT RectangularMatrixCategory}
-<<category RMATCAT RectangularMatrixCategory>>=
-)abbrev category RMATCAT RectangularMatrixCategory
-++ Authors: Grabmeier, Gschnitzer, Williamson
-++ Date Created: 1987
-++ Date Last Updated: July 1990
-++ Basic Operations:
-++ Related Domains: RectangularMatrix(m,n,R)
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ Examples:
-++ References:
-++ Description:
-++   \spadtype{RectangularMatrixCategory} is a category of matrices of fixed
-++   dimensions.  The dimensions of the matrix will be parameters of the
-++   domain.  Domains in this category will be R-modules and will be
-++   non-mutable.
-RectangularMatrixCategory(m,n,R,Row,Col): Category == Definition where
-  m,n : NonNegativeInteger
-  R   : Ring
-  Row : DirectProductCategory(n,R)
-  Col : DirectProductCategory(m,R)
-
-  Definition ==> Join(BiModule(R,R),HomogeneousAggregate(R)) with
-
-    finiteAggregate
-      ++ matrices are finite
-
-    if R has CommutativeRing then Module(R)
-
---% Matrix creation
-
-    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.
-
---% Predicates
-
-    square?  : % -> Boolean
-      ++ \spad{square?(m)} returns true if m is a square matrix (i.e. 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 \spad{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 \spad{i} and j)
-      ++ and false otherwise.
-
---% Size inquiries
-
-    minRowIndex : % -> Integer
-      ++ \spad{minRowIndex(m)} returns the index of the 'first' row of the
-      ++ matrix m.
-    maxRowIndex : % -> Integer
-      ++ \spad{maxRowIndex(m)} returns the index of the 'last' row of the
-      ++ matrix m.
-    minColIndex : % -> Integer
-      ++ \spad{minColIndex(m)} returns the index of the 'first' column of the
-      ++ matrix m.
-    maxColIndex : % -> Integer
-      ++ \spad{maxColIndex(m)} returns the index of the 'last' column of the
-      ++ matrix m.
-    nrows : % -> NonNegativeInteger
-      ++ \spad{nrows(m)} returns the number of rows in the matrix m.
-    ncols : % -> NonNegativeInteger
-      ++ \spad{ncols(m)} returns the number of columns in the matrix m.
-
---% Part extractions
-
-    listOfLists: % -> List List R
-      ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
-      ++ of lists.
-    elt: (%,Integer,Integer) -> R
-      ++ \spad{elt(m,i,j)} returns the element in the \spad{i}th row and
-      ++ \spad{j}th column of the matrix m.
-      ++ Error: if indices are outside the proper
-      ++ ranges.
-    qelt: (%,Integer,Integer) -> R
-      ++ \spad{qelt(m,i,j)} returns the element in the \spad{i}th row and
-      ++ \spad{j}th column of
-      ++ the matrix m. Note: there is NO error check to determine if indices are
-      ++ in the proper ranges.
-    elt: (%,Integer,Integer,R) -> R
-      ++ \spad{elt(m,i,j,r)} returns the element in the \spad{i}th row and
-      ++ \spad{j}th column of the matrix m, if m has an \spad{i}th row and a
-      ++ \spad{j}th column, and returns r otherwise.
-    row: (%,Integer) -> Row
-      ++ \spad{row(m,i)} returns the \spad{i}th row of the matrix m.
-      ++ Error: if the index is outside the proper range.
-    column: (%,Integer) -> Col
-      ++ \spad{column(m,j)} returns the \spad{j}th column of the matrix m.
-      ++ Error: if the index outside the proper range.
-
---% Map and Zip
-
-    map: (R -> R,%) -> %
-      ++ \spad{map(f,a)} returns b, where \spad{b(i,j) = a(i,j)} for all i, j.
-    map:((R,R) -> R,%,%) -> %
-      ++ \spad{map(f,a,b)} returns c, where c is such that
-      ++ \spad{c(i,j) = f(a(i,j),b(i,j))} for all \spad{i}, j.
-
---% Arithmetic
-
-    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.
-   add
-     nrows x == m
-     ncols x == n
-     square? x == m = n
-
-     diagonal? x ==
-       not square? x => false
-       for i in minRowIndex x .. maxRowIndex x repeat
-         for j in minColIndex x .. maxColIndex x
-           | (j - minColIndex x) ^= (i - minRowIndex x) repeat
-             not zero? qelt(x, i, j) => return false
-       true
-
-     symmetric? x ==
-       m ^= n => false
-       mr := minRowIndex x; mc := minColIndex x
-       for i in 0..(n - 1) repeat
-         for j in (i + 1)..(n - 1) repeat
-           qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
-       true
-
-     antisymmetric? x ==
-       m ^= n => false
-       mr := minRowIndex x; mc := minColIndex x
-       for i in 0..(n - 1) repeat
-         for j in i..(n - 1) repeat
-           qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
-             return false
-       true
-
-@
-\section{category SMATCAT SquareMatrixCategory}
-<<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)
-
-@
-\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 MATCAT MatrixCategory>>
-<<category RMATCAT RectangularMatrixCategory>>
-<<category SMATCAT SquareMatrixCategory>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
