diff --git a/books/bookvol10.2.pamphlet b/books/bookvol10.2.pamphlet
index 60be62e..cb65b93 100644
--- a/books/bookvol10.2.pamphlet
+++ b/books/bookvol10.2.pamphlet
@@ -889,6 +889,7 @@ digraph pic {
 
 {\bf See:}\\
 \pageto{FullyRetractableTo}{FRETRCT}
+\pageto{GradedAlgebra}{GRALG}
 \pagefrom{Category}{CATEGORY}
 
 {\bf Exports:}\\
@@ -976,6 +977,7 @@ RetractableTo(S: Type): Category == with
 "RetractableTo(CommutativeRing)"
  [color=seagreen,href="bookvol10.2.pdf#nameddest=RETRACT"];
 "RetractableTo(CommutativeRing)" -> "RetractableTo(a:Type)"
+
 @
 <<RETRACT.dotpic>>=
 digraph pic {
@@ -1562,6 +1564,7 @@ digraph pic {
 {\bf See:}\\
 \pageto{AbelianSemiGroup}{ABELSG}
 \pageto{Finite}{FINITE}
+\pageto{GradedModule}{GRMOD}
 \pageto{HomogeneousAggregate}{HOAGG}
 \pageto{OrderedSet}{ORDSET}
 \pageto{SemiGroup}{SGROUP}
@@ -1894,6 +1897,142 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{GradedModule}{GRMOD}
+\pagepic{ps/v102gradedmodule.ps}{GRMOD}{1.00}
+
+{\bf See:}\\
+\pageto{GradedAlgebra}{GRALG}
+\pagefrom{SetCategory}{SETCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{GRMOD}{0} &
+\cross{GRMOD}{coerce} &
+\cross{GRMOD}{degree} &
+\cross{GRMOD}{hash} &
+\cross{GRMOD}{latex} \\
+\cross{GRMOD}{?\~{}=?} &
+\cross{GRMOD}{?*?} &
+\cross{GRMOD}{?+?} &
+\cross{GRMOD}{?-?} &
+\cross{GRMOD}{-?} \\
+\cross{GRMOD}{?=?} &&&&
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ 0 : () -> %                          
+ degree : % -> E                      
+ ?*? : (%,R) -> %                     
+ ?*? : (R,%) -> %
+ -? : % -> %                          
+ ?+? : (%,%) -> %                     
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ ?-? : (%,%) -> %
+\end{verbatim}
+
+These exports come from SetCategory():
+\begin{verbatim}
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ ?~=? : (%,%) -> Boolean
+ ?=? : (%,%) -> Boolean
+\end{verbatim}
+
+<<category GRMOD GradedModule>>=
+)abbrev category GRMOD GradedModule
+++ Author: Stephen M. Watt
+++ Date Created: May 20, 1991
+++ Date Last Updated: May 20, 1991
+++ Basic Operations: +, *, degree
+++ Related Domains: CartesianTensor(n,dim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: graded module, tensor, multi-linear algebra
+++ Examples:
+++ References: Algebra 2d Edition, MacLane and Birkhoff, MacMillan 1979
+++ Description:
+++  GradedModule(R,E) denotes ``E-graded R-module'', i.e. collection of
+++  R-modules indexed by an abelian monoid E.
+++  An element \spad{g} of \spad{G[s]} for some specific \spad{s} in \spad{E}
+++  is said to be an element of \spad{G} with {\em degree} \spad{s}.
+++  Sums are defined in each module \spad{G[s]} so two elements of \spad{G}
+++  have a sum if they have the same degree.
+++
+++  Morphisms can be defined and composed by degree to give the
+++  mathematical category of graded modules.
+
+GradedModule(R: CommutativeRing, E: AbelianMonoid): Category ==
+    SetCategory with
+        degree: % -> E
+            ++ degree(g) names the degree of g.  The set of all elements
+            ++ of a given degree form an R-module.
+        0: constant -> %
+            ++ 0 denotes the zero of degree 0.
+        _*: (R, %) -> %
+            ++ r*g is left module multiplication.
+        _*: (%, R) -> %
+            ++ g*r is right module multiplication.
+
+        _-: % -> %
+            ++ -g is the additive inverse of g in the module of elements
+            ++ of the same grade as g.
+        _+: (%, %) -> %
+            ++ g+h is the sum of g and h in the module of elements of
+            ++ the same degree as g and h.  Error: if g and h
+            ++ have different degrees.
+        _-: (%, %) -> %
+            ++ g-h is the difference of g and h in the module of elements of
+            ++ the same degree as g and h.  Error: if g and h
+            ++ have different degrees.
+  add
+        (x: %) - (y: %) == x+(-y)
+
+@
+<<GRMOD.dotabb>>=
+"GRMOD"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=GRMOD"];
+"GRMOD" -> "SETCAT"
+
+@
+<<GRMOD.dotfull>>=
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=GRMOD"];
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)" -> "SetCategory()"
+
+@
+<<GRMOD.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)" [color=lightblue];
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)" -> "SetCategory()"
+
+"SetCategory()" [color=lightblue];
+"SetCategory()" -> "BasicType()"
+"SetCategory()" -> "CoercibleTo(OutputForm)"
+
+"BasicType()" [color=lightblue];
+"BasicType()" -> "Category"
+
+"CoercibleTo(OutputForm)" [color=seagreen];
+"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+
+"CoercibleTo(a:Type)" [color=lightblue];
+"CoercibleTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{HomogeneousAggregate}{HOAGG}
 \pagepic{ps/v102homogeneousaggregate.ps}{HOAGG}{1.00}
 
@@ -2125,6 +2264,145 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{Monad}{MONAD}
+\pagepic{ps/v102monad.ps}{MONAD}{0.70}
+
+{\bf See:}\\
+\pageto{MonadWithUnit}{MONADWU}
+\pageto{NonAssociativeRng}{NARNG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{MONAD}{coerce} &
+\cross{MONAD}{hash} &
+\cross{MONAD}{latex} &
+\cross{MONAD}{leftPower} &
+\cross{MONAD}{rightPower} \\
+\cross{MONAD}{?**?} &
+\cross{MONAD}{?*?} &
+\cross{MONAD}{?=?} &
+\cross{MONAD}{?\~{}=?} &
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ ?*? : (%,%) -> %                     
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from SetCategory():
+\begin{verbatim}
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger            
+ latex : % -> String
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+\end{verbatim}
+
+<<category MONAD Monad>>=
+)abbrev category MONAD Monad
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: *, **
+++ Related Constructors: SemiGroup, Monoid, MonadWithUnit
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Monad,  binary operation
+++ Reference:
+++  N. Jacobson: Structure and Representations of Jordan Algebras
+++  AMS, Providence, 1968
+++ Description:
+++  Monad is the class of all multiplicative monads, i.e. sets
+++  with a binary operation.
+Monad(): Category == SetCategory with
+      "*": (%,%) -> %
+        ++ a*b is the product of \spad{a} and b in a set with
+        ++ a binary operation.
+      rightPower: (%,PositiveInteger) -> %
+        ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
+        ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
+        ++ \spad{rightPower(a,1) := a}.
+      leftPower: (%,PositiveInteger) -> %
+        ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
+        ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
+        ++ \spad{leftPower(a,1) := a}.
+      "**": (%,PositiveInteger) -> %
+        ++ a**n returns the \spad{n}-th power of \spad{a},
+        ++ defined by repeated squaring.
+    add
+      import RepeatedSquaring(%)
+      x:% ** n:PositiveInteger == expt(x,n)
+      rightPower(a,n) ==
+--        one? n => a
+        (n = 1) => a
+        res := a
+        for i in 1..(n-1) repeat res := res * a
+        res
+      leftPower(a,n) ==
+--        one? n => a
+        (n = 1) => a
+        res := a
+        for i in 1..(n-1) repeat res := a * res
+        res
+
+@
+<<MONAD.dotabb>>=
+"MONAD"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MONAD"];
+"MONAD" -> "SETCAT"
+
+@
+<<MONAD.dotfull>>=
+"Monad()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MONAD"];
+"Monad()" -> "SetCategory()"
+"Monad()" -> "RepeatedSquaring(Monad)"
+
+@
+<<MONAD.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SetCategory()"
+"Monad()" -> "RepeatedSquaring(Monad)"
+
+"RepeatedSquaring(Monad)" [color="#00EE00"];
+"RepeatedSquaring(Monad)" -> "RepeatedSquaring(a:SetCategory)"
+
+"RepeatedSquaring(a:SetCategory)" [color="#00EE00"];
+"RepeatedSquaring(a:SetCategory)" -> "Package"
+
+"Package" [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"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OrderedSet}{ORDSET}
 \pagepic{ps/v102orderedset.ps}{ORDSET}{1.00}
 
@@ -2626,552 +2904,6 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\pagehead{TwoDimensionalArrayCategory}{ARR2CAT}
-\pagepic{ps/v102twodimensionalarraycategory.ps}{ARR2CAT}{0.60}
-
-TwoDimensionalArrayCategory is a general array category which
-allows different representations and indexing schemes.
-Rows and columns may be extracted with rows returned as objects
-of type Row and columns returned as objects of type Col.
-The index of the 'first' row may be obtained by calling the
-function 'minRowIndex'.  The index of the 'first' column may
-be obtained by calling the function 'minColIndex'.  The index of
-the first element of a 'Row' is the same as the index of the
-first column in an array and vice versa.
-
-{\bf See:}\\
-\pagefrom{HomogeneousAggregate}{HOAGG}
-
-{\bf Exports:}\\
-\begin{tabular}{lllll}
-\cross{ARR2CAT}{any?} &
-\cross{ARR2CAT}{column} &
-\cross{ARR2CAT}{coerce} &
-\cross{ARR2CAT}{copy} &
-\cross{ARR2CAT}{count} \\
-\cross{ARR2CAT}{elt} &
-\cross{ARR2CAT}{empty} &
-\cross{ARR2CAT}{empty?} &
-\cross{ARR2CAT}{eq?} &
-\cross{ARR2CAT}{eval} \\
-\cross{ARR2CAT}{every?} &
-\cross{ARR2CAT}{fill!} &
-\cross{ARR2CAT}{hash} &
-\cross{ARR2CAT}{latex} &
-\cross{ARR2CAT}{less?} \\
-\cross{ARR2CAT}{map} &
-\cross{ARR2CAT}{map!} &
-\cross{ARR2CAT}{maxColIndex} &
-\cross{ARR2CAT}{maxRowIndex} &
-\cross{ARR2CAT}{member?} \\
-\cross{ARR2CAT}{members} &
-\cross{ARR2CAT}{minColIndex} &
-\cross{ARR2CAT}{minRowIndex} &
-\cross{ARR2CAT}{more?} &
-\cross{ARR2CAT}{ncols} \\
-\cross{ARR2CAT}{new} &
-\cross{ARR2CAT}{nrows} &
-\cross{ARR2CAT}{parts} &
-\cross{ARR2CAT}{qelt} &
-\cross{ARR2CAT}{qsetelt!} \\
-\cross{ARR2CAT}{row} &
-\cross{ARR2CAT}{sample} &
-\cross{ARR2CAT}{setColumn!} &
-\cross{ARR2CAT}{setRow!} &
-\cross{ARR2CAT}{setelt} \\
-\cross{ARR2CAT}{size?} &
-\cross{ARR2CAT}{\#?} &
-\cross{ARR2CAT}{?=?} &
-\cross{ARR2CAT}{?\~{}=?} &
-\end{tabular}
-
-{\bf Attributes Exported:}
-\begin{itemize}
-\item {\bf \cross{ARR2CAT}{finiteAggregate}}
-is true if it is an aggregate with a finite number of elements.
-\item {\bf \cross{ARR2CAT}{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.
-\end{itemize}
-
-{\bf Attributes Used:}
-\begin{itemize}
-\item {\bf \cross{ARR2CAT}{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.
-\end{itemize}
-
-These are directly exported but not implemented:
-\begin{verbatim}
- elt : (%,Integer,Integer) -> R
- maxColIndex : % -> Integer           
- maxRowIndex : % -> Integer
- minColIndex : % -> Integer           
- minRowIndex : % -> Integer
- new : (NonNegativeInteger,NonNegativeInteger,R) -> %
- ncols : % -> NonNegativeInteger      
- nrows : % -> NonNegativeInteger
- qelt : (%,Integer,Integer) -> R
- qsetelt! : (%,Integer,Integer,R) -> R
- setelt : (%,Integer,Integer,R) -> R
-\end{verbatim}
-
-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          
- count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
- elt : (%,Integer,Integer,R) -> R     
- every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
- fill! : (%,R) -> %
- less? : (%,NonNegativeInteger) -> Boolean
- map : ((R -> R),%) -> %              
- map : (((R,R) -> R),%,%) -> %
- map : (((R,R) -> R),%,%,R) -> %      
- map! : ((R -> R),%) -> %
- member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
- more? : (%,NonNegativeInteger) -> Boolean
- parts : % -> List R                  
- row : (%,Integer) -> Row             
- setColumn! : (%,Integer,Col) -> %
- setRow! : (%,Integer,Row) -> %       
- size? : (%,NonNegativeInteger) -> Boolean
- #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?=? : (%,%) -> Boolean if R has SETCAT
-\end{verbatim}
-
-These exports come from HomogeneousAggregate(R:Type)
-\begin{verbatim}
- 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
- hash : % -> SingleInteger if R has SETCAT
- latex : % -> String if R has SETCAT
- members : % -> List R if $ has finiteAggregate
- sample : () -> %
- ?~=? : (%,%) -> Boolean if R has SETCAT
-\end{verbatim}
-
-<<category ARR2CAT TwoDimensionalArrayCategory>>=
-)abbrev category ARR2CAT TwoDimensionalArrayCategory
-++ Two dimensional array categories and domains
-++ Author:
-++ Date Created: 27 October 1989
-++ Date Last Updated: 27 June 1990
-++ Keywords: array, data structure
-++ Examples:
-++ References:
-TwoDimensionalArrayCategory(R,Row,Col): Category == Definition where
- R   : Type
- Row : FiniteLinearAggregate R
- Col : FiniteLinearAggregate R
-
- Definition == HomogeneousAggregate(R) with
-
-   shallowlyMutable
-    ++ one may destructively alter arrays
-
-   finiteAggregate
-    ++ two-dimensional arrays are finite
-
---% Array creation
-
-   new: (NonNegativeInteger,NonNegativeInteger,R) -> %
-    ++ new(m,n,r) is an m-by-n array all of whose entries are r
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,0)
-    
-   fill_!: (%,R) -> %
-    ++ fill!(m,r) fills m with r's
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,0)
-    ++X fill!(arr,10)
-
---% Size inquiries
-
-   minRowIndex : % -> Integer
-    ++ minRowIndex(m) returns the index of the 'first' row of the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X minRowIndex(arr)
-
-   maxRowIndex : % -> Integer
-    ++ maxRowIndex(m) returns the index of the 'last' row of the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X maxRowIndex(arr)
-
-   minColIndex : % -> Integer
-    ++ minColIndex(m) returns the index of the 'first' column of the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X minColIndex(arr)
-
-   maxColIndex : % -> Integer
-    ++ maxColIndex(m) returns the index of the 'last' column of the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X maxColIndex(arr)
-
-   nrows : % -> NonNegativeInteger
-    ++ nrows(m) returns the number of rows in the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X nrows(arr)
-
-   ncols : % -> NonNegativeInteger
-    ++ ncols(m) returns the number of columns in the array m
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X ncols(arr)
-
---% Part extractions
-
-   elt: (%,Integer,Integer) -> R
-    ++ elt(m,i,j) returns the element in the ith row and jth
-    ++ column of the array m
-    ++ error check to determine if indices are in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X elt(arr,1,1)
-
-   qelt: (%,Integer,Integer) -> R
-    ++ qelt(m,i,j) returns the element in the ith row and jth
-    ++ column of the array m
-    ++ NO error check to determine if indices are in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X qelt(arr,1,1)
-
-   elt: (%,Integer,Integer,R) -> R
-    ++ elt(m,i,j,r) returns the element in the ith row and jth
-    ++ column of the array m, if m has an ith row and a jth column,
-    ++ and returns r otherwise
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X elt(arr,1,1,6)
-    ++X elt(arr,1,10,6)
-
-   row: (%,Integer) -> Row
-    ++ row(m,i) returns the ith row of m
-    ++ error check to determine if index is in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X row(arr,1)
-
-   column: (%,Integer) -> Col
-    ++ column(m,j) returns the jth column of m
-    ++ error check to determine if index is in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X column(arr,1)
-
-   parts: % -> List R
-    ++ parts(m) returns a list of the elements of m in row major order
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X parts(arr)
-
---% Part assignments
-
-   setelt: (%,Integer,Integer,R) -> R
-    -- will become setelt_!
-    ++ setelt(m,i,j,r) sets the element in the ith row and jth
-    ++ column of m to r
-    ++ error check to determine if indices are in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,0)
-    ++X setelt(arr,1,1,17)
-
-   qsetelt_!: (%,Integer,Integer,R) -> R
-    ++ qsetelt!(m,i,j,r) sets the element in the ith row and jth
-    ++ column of m to r
-    ++ NO error check to determine if indices are in proper ranges
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,0)
-    ++X qsetelt!(arr,1,1,17)
-
-   setRow_!: (%,Integer,Row) -> %
-    ++ setRow!(m,i,v) sets to ith row of m to v
-    ++
-    ++X T1:=TwoDimensionalArray Integer
-    ++X arr:T1:= new(5,4,0)
-    ++X T2:=OneDimensionalArray Integer
-    ++X arow:=construct([1,2,3,4]::List(INT))$T2
-    ++X setRow!(arr,1,arow)$T1
-
-   setColumn_!: (%,Integer,Col) -> %
-    ++ setColumn!(m,j,v) sets to jth column of m to v
-    ++
-    ++X T1:=TwoDimensionalArray Integer
-    ++X arr:T1:= new(5,4,0)
-    ++X T2:=OneDimensionalArray Integer
-    ++X acol:=construct([1,2,3,4,5]::List(INT))$T2
-    ++X setColumn!(arr,1,acol)$T1
-
---% Map and Zip
-
-   map: (R -> R,%) -> %
-    ++ map(f,a) returns \spad{b}, where \spad{b(i,j) = f(a(i,j))} 
-    ++ for all \spad{i, j}
-    ++
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X map(-,arr)
-    ++X map((x +-> x + x),arr)
-
-   map_!: (R -> R,%) -> %
-    ++ map!(f,a)  assign \spad{a(i,j)} to \spad{f(a(i,j))} 
-    ++ for all \spad{i, j}
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X map!(-,arr)
-
-   map:((R,R) -> R,%,%) -> %
-    ++ map(f,a,b) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))}
-    ++ for all \spad{i, j}
-    ++
-    ++X adder(a:Integer,b:Integer):Integer == a+b
-    ++X arr : ARRAY2 INT := new(5,4,10)
-    ++X map(adder,arr,arr)
-
-   map:((R,R) -> R,%,%,R) -> %
-    ++ map(f,a,b,r) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))}
-    ++ when both \spad{a(i,j)} and \spad{b(i,j)} exist;
-    ++ else \spad{c(i,j) = f(r, b(i,j))} when \spad{a(i,j)} does not exist;
-    ++ else \spad{c(i,j) = f(a(i,j),r)} when \spad{b(i,j)} does not exist;
-    ++ otherwise \spad{c(i,j) = f(r,r)}.
-    ++
-    ++X adder(a:Integer,b:Integer):Integer == a+b
-    ++X arr1 : ARRAY2 INT := new(5,4,10)
-    ++X arr2 : ARRAY2 INT := new(3,3,10)
-    ++X map(adder,arr1,arr2,17)
-
-  add
-
---% Predicates
-
-    any?(f,m) ==
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          f(qelt(m,i,j)) => return true
-      false
-
-    every?(f,m) ==
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          not f(qelt(m,i,j)) => return false
-      true
-
-    size?(m,n) == nrows(m) * ncols(m) = n
-    less?(m,n) == nrows(m) * ncols(m) < n
-    more?(m,n) == nrows(m) * ncols(m) > n
-
---% Size inquiries
-
-    # m == nrows(m) * ncols(m)
-
---% Part extractions
-
-    elt(m,i,j,r) ==
-      i < minRowIndex(m) or i > maxRowIndex(m) => r
-      j < minColIndex(m) or j > maxColIndex(m) => r
-      qelt(m,i,j)
-
-    count(f:R -> Boolean,m:%) ==
-      num : NonNegativeInteger := 0
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          if f(qelt(m,i,j)) then num := num + 1
-      num
-
-    parts m ==
-      entryList : List R := nil()
-      for i in maxRowIndex(m)..minRowIndex(m) by -1 repeat
-        for j in maxColIndex(m)..minColIndex(m) by -1 repeat
-          entryList := concat(qelt(m,i,j),entryList)
-      entryList
-
---% Creation
-
-    copy m ==
-      ans := new(nrows m,ncols m,NIL$Lisp)
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          qsetelt_!(ans,i,j,qelt(m,i,j))
-      ans
-
-    fill_!(m,r) ==
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          qsetelt_!(m,i,j,r)
-      m
-
-    map(f,m) ==
-      ans := new(nrows m,ncols m,NIL$Lisp)
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          qsetelt_!(ans,i,j,f(qelt(m,i,j)))
-      ans
-
-    map_!(f,m) ==
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          qsetelt_!(m,i,j,f(qelt(m,i,j)))
-      m
-
-    map(f,m,n) ==
-      (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) =>
-        error "map: arguments must have same dimensions"
-      ans := new(nrows m,ncols m,NIL$Lisp)
-      for i in minRowIndex(m)..maxRowIndex(m) repeat
-        for j in minColIndex(m)..maxColIndex(m) repeat
-          qsetelt_!(ans,i,j,f(qelt(m,i,j),qelt(n,i,j)))
-      ans
-
-    map(f,m,n,r) ==
-      maxRow := max(maxRowIndex m,maxRowIndex n)
-      maxCol := max(maxColIndex m,maxColIndex n)
-      ans := new(max(nrows m,nrows n),max(ncols m,ncols n),NIL$Lisp)
-      for i in minRowIndex(m)..maxRow repeat
-        for j in minColIndex(m)..maxCol repeat
-          qsetelt_!(ans,i,j,f(elt(m,i,j,r),elt(n,i,j,r)))
-      ans
-
-    setRow_!(m,i,v) ==
-      i < minRowIndex(m) or i > maxRowIndex(m) =>
-        error "setRow!: index out of range"
-      for j in minColIndex(m)..maxColIndex(m) _
-        for k in minIndex(v)..maxIndex(v) repeat
-          qsetelt_!(m,i,j,v.k)
-      m
-
-    setColumn_!(m,j,v) ==
-      j < minColIndex(m) or j > maxColIndex(m) =>
-        error "setColumn!: index out of range"
-      for i in minRowIndex(m)..maxRowIndex(m) _
-        for k in minIndex(v)..maxIndex(v) repeat
-          qsetelt_!(m,i,j,v.k)
-      m
-
-    if R has _= : (R,R) -> Boolean then
-
-      m = n ==
-        eq?(m,n) => true
-        (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) => false
-        for i in minRowIndex(m)..maxRowIndex(m) repeat
-          for j in minColIndex(m)..maxColIndex(m) repeat
-            not (qelt(m,i,j) = qelt(n,i,j)) => return false
-        true
-
-      member?(r,m) ==
-        for i in minRowIndex(m)..maxRowIndex(m) repeat
-          for j in minColIndex(m)..maxColIndex(m) repeat
-            qelt(m,i,j) = r => return true
-        false
-
-      count(r:R,m:%) == count(#1 = r,m)
-
-    if Row has shallowlyMutable then
-
-      row(m,i) ==
-        i < minRowIndex(m) or i > maxRowIndex(m) =>
-          error "row: index out of range"
-        v : Row := new(ncols m,NIL$Lisp)
-        for j in minColIndex(m)..maxColIndex(m) _
-          for k in minIndex(v)..maxIndex(v) repeat
-            qsetelt_!(v,k,qelt(m,i,j))
-        v
-
-    if Col has shallowlyMutable then
-
-      column(m,j) ==
-        j < minColIndex(m) or j > maxColIndex(m) =>
-          error "column: index out of range"
-        v : Col := new(nrows m,NIL$Lisp)
-        for i in minRowIndex(m)..maxRowIndex(m) _
-          for k in minIndex(v)..maxIndex(v) repeat
-            qsetelt_!(v,k,qelt(m,i,j))
-        v
-
-    if R has CoercibleTo(OutputForm) then
-
-      coerce(m:%) ==
-        l : List List OutputForm
-        l := [[qelt(m,i,j) :: OutputForm _
-                  for j in minColIndex(m)..maxColIndex(m)] _
-                  for i in minRowIndex(m)..maxRowIndex(m)]
-        matrix l
-
-@
-<<ARR2CAT.dotabb>>=
-"ARR2CAT"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
-"ARR2CAT" -> "HOAGG"
-
-@
-<<ARR2CAT.dotfull>>=
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
-"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
-    -> "HomogeneousAggregate(a:Type)"
-
-"TwoDimensionalArrayCategory(a:Type,d:IndexedOneDimensionalArray(a,b),e:IndexedOneDimensionalArray(a,c))"
- [color=seagreen,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
-"TwoDimensionalArrayCategory(a:Type,d:IndexedOneDimensionalArray(a,b),e:IndexedOneDimensionalArray(a,c))"
--> "TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
-
-@
-<<ARR2CAT.dotpic>>=
-digraph pic {
- fontsize=10;
- bgcolor="#FFFF66";
- node [shape=box, color=white, style=filled];
-
-"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{BagAggregate}{BGAGG}
 \pagepic{ps/v102bagaggregate.ps}{BGAGG}{1.00}
 
@@ -3594,6 +3326,161 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{GradedAlgebra}{GRALG}
+\pagepic{ps/v102gradedalgebra.ps}{GRALG}{0.75}
+
+{\bf See:}\\
+\pagefrom{GradedModule}{GRMOD}
+\pagefrom{RetractableTo}{RETRACT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{GRALG}{0} &
+\cross{GRALG}{1} &
+\cross{GRALG}{coerce} &
+\cross{GRALG}{degree} &
+\cross{GRALG}{hash} \\
+\cross{GRALG}{latex} &
+\cross{GRALG}{product} &
+\cross{GRALG}{retract} &
+\cross{GRALG}{retractIfCan} &
+\cross{GRALG}{?\~{}=?} \\
+\cross{GRALG}{?*?} &
+\cross{GRALG}{?+?} &
+\cross{GRALG}{?-?} &
+\cross{GRALG}{-?} &
+\cross{GRALG}{?=?} \\
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ product : (%,%) -> %
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ ?*? : (%,R) -> %                     
+ ?*? : (R,%) -> %
+\end{verbatim}
+
+These exports come from GradedModule(R, E)\\
+where R:CommutativeRing and E:AbelianMonoid:
+\begin{verbatim}
+ coerce : % -> OutputForm
+ degree : % -> E                      
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ ?~=? : (%,%) -> Boolean
+ ?=? : (%,%) -> Boolean
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?+? : (%,%) -> %                     
+\end{verbatim}
+
+These exports come from ,RetractableTo(R:CommutativeRing):
+\begin{verbatim}
+ coerce : R -> %                      
+ retract : % -> R                     
+ retractIfCan : % -> Union(R,"failed")
+\end{verbatim}
+
+<<category GRALG GradedAlgebra>>=
+)abbrev category GRALG GradedAlgebra
+++ Author: Stephen M. Watt
+++ Date Created: May 20, 1991
+++ Date Last Updated: May 20, 1991
+++ Basic Operations: +, *, degree
+++ Related Domains: CartesianTensor(n,dim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: graded module, tensor, multi-linear algebra
+++ Examples:
+++ References: Encyclopedic Dictionary of Mathematics, MIT Press, 1977
+++ Description:
+++  GradedAlgebra(R,E) denotes ``E-graded R-algebra''.
+++  A graded algebra is a graded module together with a degree preserving
+++  R-linear map, called the {\em product}.
+++
+++  The name ``product'' is written out in full so inner and outer products
+++  with the same mapping type can be distinguished by name.
+
+GradedAlgebra(R: CommutativeRing, E: AbelianMonoid): Category ==
+    Join(GradedModule(R, E),RetractableTo(R)) with
+        1: constant -> %
+            ++ 1 is the identity for \spad{product}.
+        product: (%, %) -> %
+            ++ product(a,b) is the degree-preserving R-linear product:
+            ++
+            ++   \spad{degree product(a,b) = degree a + degree b}
+            ++   \spad{product(a1+a2,b) = product(a1,b) + product(a2,b)}
+            ++   \spad{product(a,b1+b2) = product(a,b1) + product(a,b2)}
+            ++   \spad{product(r*a,b) = product(a,r*b) = r*product(a,b)}
+            ++   \spad{product(a,product(b,c)) = product(product(a,b),c)}
+  add
+        if not (R is %) then
+            0: % == (0$R)::%
+            1: % == 1$R::%
+            (r: R)*(x: %) == product(r::%, x)
+            (x: %)*(r: R) == product(x, r::%)
+
+@
+<<GRALG.dotabb>>=
+"GRALG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=GRALG"];
+"GRALG" -> "GRMOD"
+"GRALG" -> "RETRACT"
+
+@
+<<GRALG.dotfull>>=
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=GRALG"];
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
+    "GradedModule(a:CommutativeRing,b:AbelianMonoid)"
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
+    "RetractableTo(CommutativeRing)"
+@
+<<GRALG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" [color=lightblue];
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
+    "GradedModule(a:CommutativeRing,b:AbelianMonoid)"
+"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
+    "RetractableTo(CommutativeRing)"
+
+"RetractableTo(CommutativeRing)" [color=seagreen];
+"RetractableTo(CommutativeRing)" -> "RetractableTo(a:Type)"
+
+"RetractableTo(a:Type)" [color=lightblue];
+"RetractableTo(a:Type)" -> "Category"
+
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)" [color=lightblue];
+"GradedModule(a:CommutativeRing,b:AbelianMonoid)" -> "SetCategory()"
+
+"SetCategory()" [color=lightblue];
+"SetCategory()" -> "BasicType()"
+"SetCategory()" -> "CoercibleTo(OutputForm)"
+
+"BasicType()" [color=lightblue];
+"BasicType()" -> "Category"
+
+"CoercibleTo(OutputForm)" [color=seagreen];
+"CoercibleTo(OutputForm)" -> "CoercibleTo(a:Type)"
+
+"CoercibleTo(a:Type)" [color=lightblue];
+"CoercibleTo(a:Type)" -> "Category"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{IndexedAggregate}{IXAGG}
 \pagepic{ps/v102indexedaggregate.ps}{IXAGG}{1.00}
 
@@ -3867,6 +3754,181 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{MonadWithUnit}{MONADWU}
+\pagepic{ps/v102monadwithunit.ps}{MONADWU}{0.75}
+
+{\bf See:}\\
+\pageto{NonAssociativeRing}{NASRING}
+\pagefrom{Monad}{MONAD}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{MONADWU}{1} &
+\cross{MONADWU}{coerce} &
+\cross{MONADWU}{hash} &
+\cross{MONADWU}{latex} &
+\cross{MONADWU}{one?} \\
+\cross{MONADWU}{recip} &
+\cross{MONADWU}{leftPower} &
+\cross{MONADWU}{leftRecip} &
+\cross{MONADWU}{rightPower} &
+\cross{MONADWU}{rightRecip} \\
+\cross{MONADWU}{?*?} &
+\cross{MONADWU}{?\~{}=?} &
+\cross{MONADWU}{?**?} &
+\cross{MONADWU}{?=?} &
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ 1 : () -> %
+ leftRecip : % -> Union(%,"failed")
+ recip : % -> Union(%,"failed")       
+ rightRecip : % -> Union(%,"failed")
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ leftPower : (%,NonNegativeInteger) -> %
+ one? : % -> Boolean
+ rightPower : (%,NonNegativeInteger) -> %
+ ?**? : (%,NonNegativeInteger) -> %
+\end{verbatim}
+
+These exports come from Monad():
+\begin{verbatim}
+ coerce : % -> OutputForm             
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ ?**? : (%,PositiveInteger) -> %
+ ?*? : (%,%) -> %                     
+ ?~=? : (%,%) -> Boolean
+ ?=? : (%,%) -> Boolean               
+\end{verbatim}
+
+<<category MONADWU MonadWithUnit>>=
+)abbrev category MONADWU MonadWithUnit
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: *, **, 1
+++ Related Constructors: SemiGroup, Monoid, Monad
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: Monad with unit, binary operation
+++ Reference:
+++  N. Jacobson: Structure and Representations of Jordan Algebras
+++  AMS, Providence, 1968
+++ Description:
+++  MonadWithUnit is the class of multiplicative monads with unit,
+++  i.e. sets with a binary operation and a unit element.
+++ Axioms
+++    leftIdentity("*":(%,%)->%,1)   \tab{30} 1*x=x
+++    rightIdentity("*":(%,%)->%,1)  \tab{30} x*1=x
+++ Common Additional Axioms
+++    unitsKnown---if "recip" says "failed", that PROVES input wasn't a unit
+MonadWithUnit(): Category == Monad with
+      1: constant ->  %
+        ++ 1 returns the unit element, denoted by 1.
+      one?: % -> Boolean
+        ++ one?(a) tests whether \spad{a} is the unit 1.
+      rightPower: (%,NonNegativeInteger) -> %
+        ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
+        ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
+        ++ \spad{rightPower(a,0) := 1}.
+      leftPower: (%,NonNegativeInteger) -> %
+        ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
+        ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
+        ++ \spad{leftPower(a,0) := 1}.
+      "**": (%,NonNegativeInteger) -> %
+        ++ \spad{a**n} returns the \spad{n}-th power of \spad{a},
+        ++ defined by repeated squaring.
+      recip: % -> Union(%,"failed")
+        ++ recip(a) returns an element, which is both a left and a right
+        ++ inverse of \spad{a},
+        ++ or \spad{"failed"} if such an element doesn't exist or cannot
+        ++ be determined (see unitsKnown).
+      leftRecip: % -> Union(%,"failed")
+        ++ leftRecip(a) returns an element, which is a left inverse of 
+        ++ \spad{a}, or \spad{"failed"} if such an element doesn't exist 
+        ++ or cannot be determined (see unitsKnown).
+      rightRecip: % -> Union(%,"failed")
+        ++ rightRecip(a) returns an element, which is a right inverse of
+        ++ \spad{a}, or \spad{"failed"} if such an element doesn't exist
+        ++ or cannot be determined (see unitsKnown).
+    add
+      import RepeatedSquaring(%)
+      one? x == x = 1
+      x:% ** n:NonNegativeInteger ==
+         zero? n => 1
+         expt(x,n pretend PositiveInteger)
+      rightPower(a,n) ==
+        zero? n => 1
+        res := 1
+        for i in 1..n repeat res := res * a
+        res
+      leftPower(a,n) ==
+        zero? n => 1
+        res := 1
+        for i in 1..n repeat res := a * res
+        res
+
+@
+<<MONADWU.dotabb>>=
+"MONADWU"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MONADWU"];
+"MONADWU" -> "MONAD"
+
+@
+<<MONADWU.dotfull>>=
+"MonadWithUnit()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=MONADWU"];
+"MonadWithUnit()" -> "Monad()"
+
+@
+<<MONADWU.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"MonadWithUnit()" [color=lightblue];
+"MonadWithUnit()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SetCategory()"
+"Monad()" -> "RepeatedSquaring(Monad)"
+
+"RepeatedSquaring(Monad)" [color="#00EE00"];
+"RepeatedSquaring(Monad)" -> "RepeatedSquaring(a:SetCategory)"
+
+"RepeatedSquaring(a:SetCategory)" [color="#00EE00"];
+"RepeatedSquaring(a:SetCategory)" -> "Package"
+
+"Package" [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"
+
+"Category" [color=lightblue];
+
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{Monoid}{MONOID}
 \pagepic{ps/v102monoid.ps}{MONOID}{0.75}
 
@@ -4349,6 +4411,552 @@ digraph pic {
 }
 
 @
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{TwoDimensionalArrayCategory}{ARR2CAT}
+\pagepic{ps/v102twodimensionalarraycategory.ps}{ARR2CAT}{0.60}
+
+TwoDimensionalArrayCategory is a general array category which
+allows different representations and indexing schemes.
+Rows and columns may be extracted with rows returned as objects
+of type Row and columns returned as objects of type Col.
+The index of the 'first' row may be obtained by calling the
+function 'minRowIndex'.  The index of the 'first' column may
+be obtained by calling the function 'minColIndex'.  The index of
+the first element of a 'Row' is the same as the index of the
+first column in an array and vice versa.
+
+{\bf See:}\\
+\pagefrom{HomogeneousAggregate}{HOAGG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{ARR2CAT}{any?} &
+\cross{ARR2CAT}{column} &
+\cross{ARR2CAT}{coerce} &
+\cross{ARR2CAT}{copy} &
+\cross{ARR2CAT}{count} \\
+\cross{ARR2CAT}{elt} &
+\cross{ARR2CAT}{empty} &
+\cross{ARR2CAT}{empty?} &
+\cross{ARR2CAT}{eq?} &
+\cross{ARR2CAT}{eval} \\
+\cross{ARR2CAT}{every?} &
+\cross{ARR2CAT}{fill!} &
+\cross{ARR2CAT}{hash} &
+\cross{ARR2CAT}{latex} &
+\cross{ARR2CAT}{less?} \\
+\cross{ARR2CAT}{map} &
+\cross{ARR2CAT}{map!} &
+\cross{ARR2CAT}{maxColIndex} &
+\cross{ARR2CAT}{maxRowIndex} &
+\cross{ARR2CAT}{member?} \\
+\cross{ARR2CAT}{members} &
+\cross{ARR2CAT}{minColIndex} &
+\cross{ARR2CAT}{minRowIndex} &
+\cross{ARR2CAT}{more?} &
+\cross{ARR2CAT}{ncols} \\
+\cross{ARR2CAT}{new} &
+\cross{ARR2CAT}{nrows} &
+\cross{ARR2CAT}{parts} &
+\cross{ARR2CAT}{qelt} &
+\cross{ARR2CAT}{qsetelt!} \\
+\cross{ARR2CAT}{row} &
+\cross{ARR2CAT}{sample} &
+\cross{ARR2CAT}{setColumn!} &
+\cross{ARR2CAT}{setRow!} &
+\cross{ARR2CAT}{setelt} \\
+\cross{ARR2CAT}{size?} &
+\cross{ARR2CAT}{\#?} &
+\cross{ARR2CAT}{?=?} &
+\cross{ARR2CAT}{?\~{}=?} &
+\end{tabular}
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item {\bf \cross{ARR2CAT}{finiteAggregate}}
+is true if it is an aggregate with a finite number of elements.
+\item {\bf \cross{ARR2CAT}{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.
+\end{itemize}
+
+{\bf Attributes Used:}
+\begin{itemize}
+\item {\bf \cross{ARR2CAT}{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.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ elt : (%,Integer,Integer) -> R
+ maxColIndex : % -> Integer           
+ maxRowIndex : % -> Integer
+ minColIndex : % -> Integer           
+ minRowIndex : % -> Integer
+ new : (NonNegativeInteger,NonNegativeInteger,R) -> %
+ ncols : % -> NonNegativeInteger      
+ nrows : % -> NonNegativeInteger
+ qelt : (%,Integer,Integer) -> R
+ qsetelt! : (%,Integer,Integer,R) -> R
+ setelt : (%,Integer,Integer,R) -> R
+\end{verbatim}
+
+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          
+ count : ((R -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ count : (R,%) -> NonNegativeInteger if R has SETCAT and $ has finiteAggregate
+ elt : (%,Integer,Integer,R) -> R     
+ every? : ((R -> Boolean),%) -> Boolean if $ has finiteAggregate
+ fill! : (%,R) -> %
+ less? : (%,NonNegativeInteger) -> Boolean
+ map : ((R -> R),%) -> %              
+ map : (((R,R) -> R),%,%) -> %
+ map : (((R,R) -> R),%,%,R) -> %      
+ map! : ((R -> R),%) -> %
+ member? : (R,%) -> Boolean if R has SETCAT and $ has finiteAggregate
+ more? : (%,NonNegativeInteger) -> Boolean
+ parts : % -> List R                  
+ row : (%,Integer) -> Row             
+ setColumn! : (%,Integer,Col) -> %
+ setRow! : (%,Integer,Row) -> %       
+ size? : (%,NonNegativeInteger) -> Boolean
+ #? : % -> NonNegativeInteger if $ has finiteAggregate
+ ?=? : (%,%) -> Boolean if R has SETCAT
+\end{verbatim}
+
+These exports come from HomogeneousAggregate(R:Type)
+\begin{verbatim}
+ 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
+ hash : % -> SingleInteger if R has SETCAT
+ latex : % -> String if R has SETCAT
+ members : % -> List R if $ has finiteAggregate
+ sample : () -> %
+ ?~=? : (%,%) -> Boolean if R has SETCAT
+\end{verbatim}
+
+<<category ARR2CAT TwoDimensionalArrayCategory>>=
+)abbrev category ARR2CAT TwoDimensionalArrayCategory
+++ Two dimensional array categories and domains
+++ Author:
+++ Date Created: 27 October 1989
+++ Date Last Updated: 27 June 1990
+++ Keywords: array, data structure
+++ Examples:
+++ References:
+TwoDimensionalArrayCategory(R,Row,Col): Category == Definition where
+ R   : Type
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+
+ Definition == HomogeneousAggregate(R) with
+
+   shallowlyMutable
+    ++ one may destructively alter arrays
+
+   finiteAggregate
+    ++ two-dimensional arrays are finite
+
+--% Array creation
+
+   new: (NonNegativeInteger,NonNegativeInteger,R) -> %
+    ++ new(m,n,r) is an m-by-n array all of whose entries are r
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,0)
+    
+   fill_!: (%,R) -> %
+    ++ fill!(m,r) fills m with r's
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,0)
+    ++X fill!(arr,10)
+
+--% Size inquiries
+
+   minRowIndex : % -> Integer
+    ++ minRowIndex(m) returns the index of the 'first' row of the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X minRowIndex(arr)
+
+   maxRowIndex : % -> Integer
+    ++ maxRowIndex(m) returns the index of the 'last' row of the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X maxRowIndex(arr)
+
+   minColIndex : % -> Integer
+    ++ minColIndex(m) returns the index of the 'first' column of the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X minColIndex(arr)
+
+   maxColIndex : % -> Integer
+    ++ maxColIndex(m) returns the index of the 'last' column of the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X maxColIndex(arr)
+
+   nrows : % -> NonNegativeInteger
+    ++ nrows(m) returns the number of rows in the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X nrows(arr)
+
+   ncols : % -> NonNegativeInteger
+    ++ ncols(m) returns the number of columns in the array m
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X ncols(arr)
+
+--% Part extractions
+
+   elt: (%,Integer,Integer) -> R
+    ++ elt(m,i,j) returns the element in the ith row and jth
+    ++ column of the array m
+    ++ error check to determine if indices are in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X elt(arr,1,1)
+
+   qelt: (%,Integer,Integer) -> R
+    ++ qelt(m,i,j) returns the element in the ith row and jth
+    ++ column of the array m
+    ++ NO error check to determine if indices are in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X qelt(arr,1,1)
+
+   elt: (%,Integer,Integer,R) -> R
+    ++ elt(m,i,j,r) returns the element in the ith row and jth
+    ++ column of the array m, if m has an ith row and a jth column,
+    ++ and returns r otherwise
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X elt(arr,1,1,6)
+    ++X elt(arr,1,10,6)
+
+   row: (%,Integer) -> Row
+    ++ row(m,i) returns the ith row of m
+    ++ error check to determine if index is in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X row(arr,1)
+
+   column: (%,Integer) -> Col
+    ++ column(m,j) returns the jth column of m
+    ++ error check to determine if index is in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X column(arr,1)
+
+   parts: % -> List R
+    ++ parts(m) returns a list of the elements of m in row major order
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X parts(arr)
+
+--% Part assignments
+
+   setelt: (%,Integer,Integer,R) -> R
+    -- will become setelt_!
+    ++ setelt(m,i,j,r) sets the element in the ith row and jth
+    ++ column of m to r
+    ++ error check to determine if indices are in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,0)
+    ++X setelt(arr,1,1,17)
+
+   qsetelt_!: (%,Integer,Integer,R) -> R
+    ++ qsetelt!(m,i,j,r) sets the element in the ith row and jth
+    ++ column of m to r
+    ++ NO error check to determine if indices are in proper ranges
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,0)
+    ++X qsetelt!(arr,1,1,17)
+
+   setRow_!: (%,Integer,Row) -> %
+    ++ setRow!(m,i,v) sets to ith row of m to v
+    ++
+    ++X T1:=TwoDimensionalArray Integer
+    ++X arr:T1:= new(5,4,0)
+    ++X T2:=OneDimensionalArray Integer
+    ++X arow:=construct([1,2,3,4]::List(INT))$T2
+    ++X setRow!(arr,1,arow)$T1
+
+   setColumn_!: (%,Integer,Col) -> %
+    ++ setColumn!(m,j,v) sets to jth column of m to v
+    ++
+    ++X T1:=TwoDimensionalArray Integer
+    ++X arr:T1:= new(5,4,0)
+    ++X T2:=OneDimensionalArray Integer
+    ++X acol:=construct([1,2,3,4,5]::List(INT))$T2
+    ++X setColumn!(arr,1,acol)$T1
+
+--% Map and Zip
+
+   map: (R -> R,%) -> %
+    ++ map(f,a) returns \spad{b}, where \spad{b(i,j) = f(a(i,j))} 
+    ++ for all \spad{i, j}
+    ++
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X map(-,arr)
+    ++X map((x +-> x + x),arr)
+
+   map_!: (R -> R,%) -> %
+    ++ map!(f,a)  assign \spad{a(i,j)} to \spad{f(a(i,j))} 
+    ++ for all \spad{i, j}
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X map!(-,arr)
+
+   map:((R,R) -> R,%,%) -> %
+    ++ map(f,a,b) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))}
+    ++ for all \spad{i, j}
+    ++
+    ++X adder(a:Integer,b:Integer):Integer == a+b
+    ++X arr : ARRAY2 INT := new(5,4,10)
+    ++X map(adder,arr,arr)
+
+   map:((R,R) -> R,%,%,R) -> %
+    ++ map(f,a,b,r) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))}
+    ++ when both \spad{a(i,j)} and \spad{b(i,j)} exist;
+    ++ else \spad{c(i,j) = f(r, b(i,j))} when \spad{a(i,j)} does not exist;
+    ++ else \spad{c(i,j) = f(a(i,j),r)} when \spad{b(i,j)} does not exist;
+    ++ otherwise \spad{c(i,j) = f(r,r)}.
+    ++
+    ++X adder(a:Integer,b:Integer):Integer == a+b
+    ++X arr1 : ARRAY2 INT := new(5,4,10)
+    ++X arr2 : ARRAY2 INT := new(3,3,10)
+    ++X map(adder,arr1,arr2,17)
+
+  add
+
+--% Predicates
+
+    any?(f,m) ==
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          f(qelt(m,i,j)) => return true
+      false
+
+    every?(f,m) ==
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          not f(qelt(m,i,j)) => return false
+      true
+
+    size?(m,n) == nrows(m) * ncols(m) = n
+    less?(m,n) == nrows(m) * ncols(m) < n
+    more?(m,n) == nrows(m) * ncols(m) > n
+
+--% Size inquiries
+
+    # m == nrows(m) * ncols(m)
+
+--% Part extractions
+
+    elt(m,i,j,r) ==
+      i < minRowIndex(m) or i > maxRowIndex(m) => r
+      j < minColIndex(m) or j > maxColIndex(m) => r
+      qelt(m,i,j)
+
+    count(f:R -> Boolean,m:%) ==
+      num : NonNegativeInteger := 0
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          if f(qelt(m,i,j)) then num := num + 1
+      num
+
+    parts m ==
+      entryList : List R := nil()
+      for i in maxRowIndex(m)..minRowIndex(m) by -1 repeat
+        for j in maxColIndex(m)..minColIndex(m) by -1 repeat
+          entryList := concat(qelt(m,i,j),entryList)
+      entryList
+
+--% Creation
+
+    copy m ==
+      ans := new(nrows m,ncols m,NIL$Lisp)
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          qsetelt_!(ans,i,j,qelt(m,i,j))
+      ans
+
+    fill_!(m,r) ==
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          qsetelt_!(m,i,j,r)
+      m
+
+    map(f,m) ==
+      ans := new(nrows m,ncols m,NIL$Lisp)
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          qsetelt_!(ans,i,j,f(qelt(m,i,j)))
+      ans
+
+    map_!(f,m) ==
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          qsetelt_!(m,i,j,f(qelt(m,i,j)))
+      m
+
+    map(f,m,n) ==
+      (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) =>
+        error "map: arguments must have same dimensions"
+      ans := new(nrows m,ncols m,NIL$Lisp)
+      for i in minRowIndex(m)..maxRowIndex(m) repeat
+        for j in minColIndex(m)..maxColIndex(m) repeat
+          qsetelt_!(ans,i,j,f(qelt(m,i,j),qelt(n,i,j)))
+      ans
+
+    map(f,m,n,r) ==
+      maxRow := max(maxRowIndex m,maxRowIndex n)
+      maxCol := max(maxColIndex m,maxColIndex n)
+      ans := new(max(nrows m,nrows n),max(ncols m,ncols n),NIL$Lisp)
+      for i in minRowIndex(m)..maxRow repeat
+        for j in minColIndex(m)..maxCol repeat
+          qsetelt_!(ans,i,j,f(elt(m,i,j,r),elt(n,i,j,r)))
+      ans
+
+    setRow_!(m,i,v) ==
+      i < minRowIndex(m) or i > maxRowIndex(m) =>
+        error "setRow!: index out of range"
+      for j in minColIndex(m)..maxColIndex(m) _
+        for k in minIndex(v)..maxIndex(v) repeat
+          qsetelt_!(m,i,j,v.k)
+      m
+
+    setColumn_!(m,j,v) ==
+      j < minColIndex(m) or j > maxColIndex(m) =>
+        error "setColumn!: index out of range"
+      for i in minRowIndex(m)..maxRowIndex(m) _
+        for k in minIndex(v)..maxIndex(v) repeat
+          qsetelt_!(m,i,j,v.k)
+      m
+
+    if R has _= : (R,R) -> Boolean then
+
+      m = n ==
+        eq?(m,n) => true
+        (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) => false
+        for i in minRowIndex(m)..maxRowIndex(m) repeat
+          for j in minColIndex(m)..maxColIndex(m) repeat
+            not (qelt(m,i,j) = qelt(n,i,j)) => return false
+        true
+
+      member?(r,m) ==
+        for i in minRowIndex(m)..maxRowIndex(m) repeat
+          for j in minColIndex(m)..maxColIndex(m) repeat
+            qelt(m,i,j) = r => return true
+        false
+
+      count(r:R,m:%) == count(#1 = r,m)
+
+    if Row has shallowlyMutable then
+
+      row(m,i) ==
+        i < minRowIndex(m) or i > maxRowIndex(m) =>
+          error "row: index out of range"
+        v : Row := new(ncols m,NIL$Lisp)
+        for j in minColIndex(m)..maxColIndex(m) _
+          for k in minIndex(v)..maxIndex(v) repeat
+            qsetelt_!(v,k,qelt(m,i,j))
+        v
+
+    if Col has shallowlyMutable then
+
+      column(m,j) ==
+        j < minColIndex(m) or j > maxColIndex(m) =>
+          error "column: index out of range"
+        v : Col := new(nrows m,NIL$Lisp)
+        for i in minRowIndex(m)..maxRowIndex(m) _
+          for k in minIndex(v)..maxIndex(v) repeat
+            qsetelt_!(v,k,qelt(m,i,j))
+        v
+
+    if R has CoercibleTo(OutputForm) then
+
+      coerce(m:%) ==
+        l : List List OutputForm
+        l := [[qelt(m,i,j) :: OutputForm _
+                  for j in minColIndex(m)..maxColIndex(m)] _
+                  for i in minRowIndex(m)..maxRowIndex(m)]
+        matrix l
+
+@
+<<ARR2CAT.dotabb>>=
+"ARR2CAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
+"ARR2CAT" -> "HOAGG"
+
+@
+<<ARR2CAT.dotfull>>=
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
+"TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+    -> "HomogeneousAggregate(a:Type)"
+
+"TwoDimensionalArrayCategory(a:Type,d:IndexedOneDimensionalArray(a,b),e:IndexedOneDimensionalArray(a,c))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=ARR2CAT"];
+"TwoDimensionalArrayCategory(a:Type,d:IndexedOneDimensionalArray(a,b),e:IndexedOneDimensionalArray(a,c))"
+-> "TwoDimensionalArrayCategory(a:Type,b:FiniteLinearAggregate(a),c:FiniteLinearAggregate(a))"
+
+@
+<<ARR2CAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"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];
+
+}
+
+@
 \chapter{Category Layer 5}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{BinaryRecursiveAggregate}{BRAGG}
@@ -7232,6 +7840,7 @@ digraph pic {
 
 {\bf See:}\\
 \pageto{LeftModule}{LMODULE}
+\pageto{NonAssociativeRng}{NARNG}
 \pageto{OrderedAbelianGroup}{OAGROUP}
 \pageto{RightModule}{RMODULE}
 \pageto{Rng}{RNG}
@@ -7339,6 +7948,22 @@ 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)"
@@ -9143,6 +9768,155 @@ digraph pic {
 @
 \chapter{Category Layer 7}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{NonAssociativeRng}{NARNG}
+\pagepic{ps/v102nonassociativerng.ps}{NARNG}{1.00}
+
+{\bf See:}\\
+\pageto{NonAssociativeAlgebra}{NAALG}
+\pageto{NonAssociativeRing}{NASRING}
+\pagefrom{AbelianGroup}{ABELGRP}
+\pagefrom{Monad}{MONAD}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{NARNG}{0} &
+\cross{NARNG}{antiCommutator} &
+\cross{NARNG}{associator} &
+\cross{NARNG}{coerce} &
+\cross{NARNG}{commutator} \\
+\cross{NARNG}{hash} &
+\cross{NARNG}{latex} &
+\cross{NARNG}{leftPower} &
+\cross{NARNG}{rightPower} &
+\cross{NARNG}{sample} \\
+\cross{NARNG}{subtractIfCan} &
+\cross{NARNG}{zero?} &
+\cross{NARNG}{?*?} &
+\cross{NARNG}{?**?} &
+\cross{NARNG}{?+?} \\
+\cross{NARNG}{?-?} &
+\cross{NARNG}{-?} &
+\cross{NARNG}{?=?} &
+\cross{NARNG}{?~=?} &
+\end{tabular}
+
+These are implemented by this category:
+\begin{verbatim}
+ antiCommutator : (%,%) -> %
+ associator : (%,%,%) -> %            
+ commutator : (%,%) -> %              
+\end{verbatim}
+
+These exports come from AbelianGroup():
+\begin{verbatim}
+ 0 : () -> %                          
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?~=? : (%,%) -> Boolean
+ ?*? : (PositiveInteger,%) -> %       
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?*? : (Integer,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+\end{verbatim}
+
+These exports come from Monad():
+\begin{verbatim}
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ ?*? : (%,%) -> %                     
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+<<category NARNG NonAssociativeRng>>=
+)abbrev category NARNG NonAssociativeRng
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 03 July 1991
+++ Basic Operations: +, *, -, **
+++ Related Constructors: Rng, Ring, NonAssociativeRing
+++ Also See:
+++ AMS Classifications:
+++ Keywords: not associative ring
+++ Reference:
+++  R.D. Schafer: An Introduction to Nonassociative Algebras
+++  Academic Press, New York, 1966
+++ Description:
+++  NonAssociativeRng is a basic ring-type structure, not necessarily
+++  commutative or associative, and not necessarily with unit.
+++  Axioms
+++    x*(y+z) = x*y + x*z
+++    (x+y)*z = x*z + y*z
+++  Common Additional Axioms
+++    noZeroDivisors  ab = 0 => a=0 or b=0
+NonAssociativeRng(): Category == Join(AbelianGroup,Monad)  with
+    associator: (%,%,%) -> %
+      ++ associator(a,b,c) returns \spad{(a*b)*c-a*(b*c)}.
+    commutator: (%,%) -> %
+      ++ commutator(a,b) returns \spad{a*b-b*a}.
+    antiCommutator: (%,%) -> %
+      ++ antiCommutator(a,b) returns \spad{a*b+b*a}.
+  add
+    associator(x,y,z) == (x*y)*z - x*(y*z)
+    commutator(x,y) == x*y - y*x
+    antiCommutator(x,y) == x*y + y*x
+
+@
+<<NARNG.dotabb>>=
+"NARNG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NARNG"];
+"NARNG" -> "ABELGRP"
+"NARNG" -> "MONAD"
+
+@
+<<NARNG.dotfull>>=
+"NonAssociativeRng()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NARNG"];
+"NonAssociativeRng()" -> "AbelianGroup()"
+"NonAssociativeRng()" -> "Monad()"
+
+@
+<<NARNG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "AbelianGroup()"
+"NonAssociativeRng()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
+
+"AbelianGroup()" [color=lightblue];
+"AbelianGroup()" -> "CancellationAbelianMonoid()"
+"AbelianGroup()" -> "REPDB..."
+
+"CancellationAbelianMonoid()" [color=lightblue];
+"CancellationAbelianMonoid()" -> "AbelianMonoid()"
+
+"AbelianMonoid()" [color=lightblue];
+"AbelianMonoid()" -> "AbelianSemiGroup()"
+
+"AbelianSemiGroup()" [color=lightblue];
+"AbelianSemiGroup()" -> "SETCAT..."
+"AbelianSemiGroup()" -> "REPDB..."
+
+"REPDB..." [color="#00EE00"];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OneDimensionalArrayAggregate}{A1AGG}
 \pagepic{ps/v102onedimensionalarrayaggregate.ps}{A1AGG}{1.00}
 
@@ -12694,10 +13468,6 @@ and RecKE=Record(key: Key,entry: Entry)
  ?.? : (%,Integer) -> RecKE
 \end{verbatim}
 
-These exports come from SetCategory():
-\begin{verbatim}
-\end{verbatim}
-
 <<category ALAGG AssociationListAggregate>>=
 )abbrev category ALAGG AssociationListAggregate
 ++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
@@ -13261,6 +14031,174 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{NonAssociativeRing}{NASRING}
+\pagepic{ps/v102nonassociativering.ps}{NASRING}{1.00}
+
+{\bf See:}\\
+\pagefrom{MonadWithUnit}{MONADWU}
+\pagefrom{NonAssociativeRng}{NARNG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{NASRING}{0} &
+\cross{NASRING}{1} &
+\cross{NASRING}{antiCommutator} &
+\cross{NASRING}{associator} &
+\cross{NASRING}{characteristic} \\
+\cross{NASRING}{coerce} &
+\cross{NASRING}{commutator} &
+\cross{NASRING}{hash} &
+\cross{NASRING}{latex} &
+\cross{NASRING}{leftPower} \\
+\cross{NASRING}{leftRecip} &
+\cross{NASRING}{one?} &
+\cross{NASRING}{recip} &
+\cross{NASRING}{rightPower} &
+\cross{NASRING}{rightRecip} \\
+\cross{NASRING}{sample} &
+\cross{NASRING}{subtractIfCan} &
+\cross{NASRING}{zero?} &
+\cross{NASRING}{?*?} &
+\cross{NASRING}{?~=?} \\
+\cross{NASRING}{?**?} &
+\cross{NASRING}{?+?} &
+\cross{NASRING}{?-?} &
+\cross{NASRING}{-?} &
+\cross{NASRING}{?=?} \\
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ characteristic : () -> NonNegativeInteger
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ coerce : Integer -> %                
+\end{verbatim}
+
+These exports come from NonAssociativeRng():
+\begin{verbatim}
+ 0 : () -> %
+ antiCommutator : (%,%) -> %          
+ associator : (%,%,%) -> %
+ coerce : % -> OutputForm
+ commutator : (%,%) -> %              
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?~=? : (%,%) -> Boolean
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?*? : (Integer,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from MonadWithUnit():
+\begin{verbatim}
+ 1 : () -> %                          
+ leftPower : (%,NonNegativeInteger) -> %
+ leftRecip : % -> Union(%,"failed")
+ one? : % -> Boolean
+ recip : % -> Union(%,"failed")       
+ rightPower : (%,NonNegativeInteger) -> %
+ rightRecip : % -> Union(%,"failed")
+ ?**? : (%,NonNegativeInteger) -> %
+\end{verbatim}
+
+<<category NASRING NonAssociativeRing>>=
+)abbrev category NASRING NonAssociativeRing
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +, *, -, **
+++ Related Constructors: NonAssociativeRng, Rng, Ring
+++ Also See:
+++ AMS Classifications:
+++ Keywords: non-associative ring with unit
+++ Reference:
+++  R.D. Schafer: An Introduction to Nonassociative Algebras
+++  Academic Press, New York, 1966
+++ Description:
+++  A NonAssociativeRing is a non associative rng which has a unit,
+++  the multiplication is not necessarily commutative or associative.
+NonAssociativeRing(): Category == Join(NonAssociativeRng,MonadWithUnit) with
+      characteristic: -> NonNegativeInteger
+        ++ characteristic() returns the characteristic of the ring.
+        --we can not make this a constant, since some domains are mutable
+      coerce: Integer -> %
+        ++ coerce(n) coerces the integer n to an element of the ring.
+   add
+      n:Integer
+      coerce(n) == n * 1$%
+
+@
+<<NASRING.dotabb>>=
+"NASRING"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NASRING"];
+"NASRING" -> "MONADWU"
+"NASRING" -> "NARNG"
+
+@
+<<NASRING.dotfull>>=
+"NonAssociativeRing()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NASRING"];
+"NonAssociativeRing()" -> "NonAssociativeRng()"
+"NonAssociativeRing()" -> "MonadWithUnit()"
+
+@
+<<NASRING.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"NonAssociativeRing()"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NASRING"];
+"NonAssociativeRing()" -> "NonAssociativeRng()"
+"NonAssociativeRing()" -> "MonadWithUnit()"
+
+"MonadWithUnit()" [color=lightblue];
+"MonadWithUnit()" -> "Monad()"
+
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "AbelianGroup()"
+"NonAssociativeRng()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
+
+"AbelianGroup()" [color=lightblue];
+"AbelianGroup()" -> "CancellationAbelianMonoid()"
+"AbelianGroup()" -> "REPDB..."
+
+"CancellationAbelianMonoid()" [color=lightblue];
+"CancellationAbelianMonoid()" -> "AbelianMonoid()"
+
+"AbelianMonoid()" [color=lightblue];
+"AbelianMonoid()" -> "AbelianSemiGroup()"
+
+"AbelianSemiGroup()" [color=lightblue];
+"AbelianSemiGroup()" -> "SETCAT..."
+"AbelianSemiGroup()" -> "REPDB..."
+
+"REPDB..." [color="#00EE00"];
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{OrderedAbelianGroup}{OAGROUP}
 \pagepic{ps/v102orderedabeliangroup.ps}{OAGROUP}{1.00}
 
@@ -15118,14 +16056,6 @@ These exports come from Ring():
  ?**? : (%,PositiveInteger) -> %
 \end{verbatim}
 
-These exports come from Evalable(a:Type):
-\begin{verbatim}
-\end{verbatim}
-
-These exports come from SetCategory:
-\begin{verbatim}
-\end{verbatim}
-
 <<category PDRING PartialDifferentialRing>>=
 )abbrev category PDRING PartialDifferentialRing
 ++ Author:
@@ -15635,6 +16565,7 @@ digraph pic {
 
 {\bf See:}\\
 \pageto{Algebra}{ALGEBRA}
+\pageto{NonAssociativeAlgebra}{NAALG}
 \pageto{VectorSpace}{VSPACE}
 \pagefrom{BiModule}{BMODULE}
 
@@ -15940,6 +16871,169 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{NonAssociativeAlgebra}{NAALG}
+\pagepic{ps/v102nonassociativealgebra.ps}{NAALG}{0.75}
+
+{\bf See:}\\
+\pageto{FiniteRankNonAssociativeAlgebra}{FINAALG}
+\pagefrom{Module}{MODULE}
+\pagefrom{NonAssociativeRng}{NARNG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{NAALG}{0} &
+\cross{NAALG}{antiCommutator} &
+\cross{NAALG}{associator} &
+\cross{NAALG}{coerce} &
+\cross{NAALG}{commutator} \\
+\cross{NAALG}{hash} &
+\cross{NAALG}{latex} &
+\cross{NAALG}{leftPower} &
+\cross{NAALG}{plenaryPower} &
+\cross{NAALG}{rightPower} \\
+\cross{NAALG}{sample} &
+\cross{NAALG}{subtractIfCan} &
+\cross{NAALG}{zero?} &
+\cross{NAALG}{?~=?} &
+\cross{NAALG}{?*?} \\
+\cross{NAALG}{?**?} &
+\cross{NAALG}{?+?} &
+\cross{NAALG}{?-?} &
+\cross{NAALG}{-?} &
+\cross{NAALG}{?=?} \\
+\end{tabular}
+
+These are implemented by this category:
+\begin{verbatim}
+ plenaryPower : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from NonAssociativeRng():
+\begin{verbatim}
+ 0 : () -> %                          
+ antiCommutator : (%,%) -> %
+ associator : (%,%,%) -> %            
+ coerce : % -> OutputForm
+ commutator : (%,%) -> %              
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ leftPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ sample : () -> %
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?~=? : (%,%) -> Boolean
+ ?*? : (PositiveInteger,%) -> %       
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?*? : (Integer,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?*? : (%,%) -> %                     
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from Module(R:CommutativeRing):
+\begin{verbatim}
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+\end{verbatim}
+
+<<category NAALG NonAssociativeAlgebra>>=
+)abbrev category NAALG NonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +, -, *, **
+++ Related Constructors: Algebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra
+++ Reference:
+++  R.D. Schafer: An Introduction to Nonassociative Algebras
+++  Academic Press, New York, 1966
+++ Description:
+++   NonAssociativeAlgebra is the category of non associative algebras
+++   (modules which are themselves non associative rngs).
+++   Axioms
+++      r*(a*b) = (r*a)*b = a*(r*b)
+NonAssociativeAlgebra(R:CommutativeRing): Category == _
+  Join(NonAssociativeRng, Module R) with
+    plenaryPower : (%,PositiveInteger) -> %
+      ++ plenaryPower(a,n) is recursively defined to be
+      ++ \spad{plenaryPower(a,n-1)*plenaryPower(a,n-1)} for \spad{n>1}
+      ++ and \spad{a} for \spad{n=1}.
+  add
+    plenaryPower(a,n) ==
+--      one? n => a
+      ( n = 1 ) => a
+      n1 : PositiveInteger := (n-1)::NonNegativeInteger::PositiveInteger
+      plenaryPower(a,n1) * plenaryPower(a,n1)
+
+@
+<<NAALG.dotabb>>=
+"NAALG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
+"NAALG" -> "NARNG"
+"NAALG" -> "MODULE"
+
+@
+<<NAALG.dotfull>>=
+"NonAssociativeAlgebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=NAALG"];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+@
+<<NAALG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"NonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "ABELGRP..."
+"NonAssociativeRng()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
+
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{VectorSpace}{VSPACE}
 \pagepic{ps/v102vectorspace.ps}{VSPACE}{1.00}
 
@@ -16254,6 +17348,898 @@ digraph pic {
 
 @
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{FiniteRankNonAssociativeAlgebra}{FINAALG}
+\pagepic{ps/v102finiteranknonassociativealgebra.ps}{FINAALG}{0.75}
+
+{\bf See:}\\
+\pageto{FramedNonAssociativeAlgebra}{FRNAALG}
+\pagefrom{NonAssociativeAlgebra}{NAALG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{FINAALG}{0} &
+\cross{FINAALG}{alternative?} \\
+\cross{FINAALG}{antiAssociative?} &
+\cross{FINAALG}{antiCommutative?} \\
+\cross{FINAALG}{antiCommutator} &
+\cross{FINAALG}{associative?} \\
+\cross{FINAALG}{associator} &
+\cross{FINAALG}{associatorDependence} \\
+\cross{FINAALG}{coerce} &
+\cross{FINAALG}{commutative?} \\
+\cross{FINAALG}{commutator} &
+\cross{FINAALG}{conditionsForIdempotents} \\
+\cross{FINAALG}{coordinates} &
+\cross{FINAALG}{flexible?} \\
+\cross{FINAALG}{hash} &
+\cross{FINAALG}{jacobiIdentity?} \\
+\cross{FINAALG}{jordanAdmissible?} &
+\cross{FINAALG}{jordanAlgebra?} \\
+\cross{FINAALG}{latex} &
+\cross{FINAALG}{leftAlternative?} \\
+\cross{FINAALG}{leftCharacteristicPolynomial} &
+\cross{FINAALG}{leftDiscriminant} \\
+\cross{FINAALG}{leftMinimalPolynomial} &
+\cross{FINAALG}{leftNorm} \\
+\cross{FINAALG}{leftPower} &
+\cross{FINAALG}{leftRecip} \\
+\cross{FINAALG}{leftRegularRepresentation} &
+\cross{FINAALG}{leftTrace} \\
+\cross{FINAALG}{leftTraceMatrix} &
+\cross{FINAALG}{leftUnit} \\
+\cross{FINAALG}{leftUnits} &
+\cross{FINAALG}{lieAdmissible?} \\
+\cross{FINAALG}{lieAlgebra?} &
+\cross{FINAALG}{noncommutativeJordanAlgebra?} \\
+\cross{FINAALG}{plenaryPower} &
+\cross{FINAALG}{powerAssociative?} \\
+\cross{FINAALG}{rank} &
+\cross{FINAALG}{recip} \\
+\cross{FINAALG}{represents} &
+\cross{FINAALG}{rightAlternative?} \\
+\cross{FINAALG}{rightCharacteristicPolynomial} &
+\cross{FINAALG}{rightDiscriminant} \\
+\cross{FINAALG}{rightMinimalPolynomial} &
+\cross{FINAALG}{rightNorm} \\
+\cross{FINAALG}{rightPower} &
+\cross{FINAALG}{rightRecip} \\
+\cross{FINAALG}{rightRegularRepresentation} &
+\cross{FINAALG}{rightTrace} \\
+\cross{FINAALG}{rightTraceMatrix} &
+\cross{FINAALG}{rightUnit} \\
+\cross{FINAALG}{rightUnits} &
+\cross{FINAALG}{sample} \\
+\cross{FINAALG}{someBasis} &
+\cross{FINAALG}{structuralConstants} \\
+\cross{FINAALG}{subtractIfCan} &
+\cross{FINAALG}{unit} \\
+\cross{FINAALG}{zero?} &
+\cross{FINAALG}{?*?} \\
+\cross{FINAALG}{?**?} &
+\cross{FINAALG}{?+?} \\
+\cross{FINAALG}{?-?} &
+\cross{FINAALG}{-?} \\
+\cross{FINAALG}{?=?} &
+\cross{FINAALG}{?\~{}=?} \\
+\end{tabular}
+
+
+{\bf Attributes Exported:}
+\begin{itemize}
+\item if R has IntegralDomain then {\bf \cross{ATTREG}{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.
+\end{itemize}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ conditionsForIdempotents : Vector % -> List Polynomial R
+ coordinates : (%,Vector %) -> Vector R
+ leftUnit : () -> Union(%,"failed") if R has INTDOM
+ leftUnits : () -> Union(Record(particular: %,basis: List %),"failed") if R has INTDOM
+ powerAssociative? : () -> Boolean    
+ rank : () -> PositiveInteger
+ rightUnit : () -> Union(%,"failed") if R has INTDOM
+ rightUnits : () -> Union(Record(particular: %,basis: List %),"failed") if R has INTDOM
+ someBasis : () -> Vector %
+ unit : () -> Union(%,"failed") if R has INTDOM
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ alternative? : () -> Boolean
+ antiAssociative? : () -> Boolean     
+ antiCommutative? : () -> Boolean
+ associative? : () -> Boolean
+ associatorDependence : () -> List Vector R if R has INTDOM
+ commutative? : () -> Boolean         
+ coordinates : (Vector %,Vector %) -> Matrix R
+ flexible? : () -> Boolean            
+ jacobiIdentity? : () -> Boolean      
+ jordanAdmissible? : () -> Boolean
+ jordanAlgebra? : () -> Boolean       
+ leftAlternative? : () -> Boolean     
+ leftCharacteristicPolynomial : % -> SparseUnivariatePolynomial R
+ leftDiscriminant : Vector % -> R
+ leftMinimalPolynomial : % -> SparseUnivariatePolynomial R if R has INTDOM
+ leftNorm : % -> R                    
+ leftRecip : % -> Union(%,"failed") if R has INTDOM
+ leftRegularRepresentation : (%,Vector %) -> Matrix R
+ leftTrace : % -> R
+ leftTraceMatrix : Vector % -> Matrix R
+ lieAdmissible? : () -> Boolean       
+ lieAlgebra? : () -> Boolean
+ noncommutativeJordanAlgebra? : () -> Boolean
+ recip : % -> Union(%,"failed") if R has INTDOM
+ represents : (Vector R,Vector %) -> %
+ rightAlternative? : () -> Boolean    
+ rightCharacteristicPolynomial : % -> SparseUnivariatePolynomial R
+ rightDiscriminant : Vector % -> R
+ rightMinimalPolynomial : % -> SparseUnivariatePolynomial R if R has INTDOM
+ rightNorm : % -> R                   
+ rightRecip : % -> Union(%,"failed") if R has INTDOM
+ rightRegularRepresentation : (%,Vector %) -> Matrix R
+ rightTrace : % -> R
+ rightTraceMatrix : Vector % -> Matrix R
+ structuralConstants : Vector % -> Vector Matrix R
+\end{verbatim}
+
+These exports come from NonAssociativeAlgebra(R:CommutativeRing):
+\begin{verbatim}
+ 0 : () -> %                          
+ antiCommutator : (%,%) -> %          
+ associator : (%,%,%) -> %            
+ coerce : % -> OutputForm
+ commutator : (%,%) -> %
+ hash : % -> SingleInteger
+ latex : % -> String
+ leftPower : (%,PositiveInteger) -> %
+ plenaryPower : (%,PositiveInteger) -> %
+ rightPower : (%,PositiveInteger) -> %
+ sample : () -> %                     
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean                 
+ ?~=? : (%,%) -> Boolean
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+<<category FINAALG FiniteRankNonAssociativeAlgebra>>=
+)abbrev category FINAALG FiniteRankNonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 12 June 1991
+++ Basic Operations: +,-,*,**, someBasis
+++ Related Constructors: FramedNonAssociativeAlgebra, FramedAlgebra,
+++   FiniteRankAssociativeAlgebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra, basis
+++ References:
+++   R.D. Schafer: An Introduction to Nonassociative Algebras
+++   Academic Press, New York, 1966
+++
+++   R. Wisbauer: Bimodule Structure of Algebra
+++   Lecture Notes Univ. Duesseldorf 1991
+++ Description:
+++   A FiniteRankNonAssociativeAlgebra is a non associative algebra over
+++   a commutative ring R which is a free \spad{R}-module of finite rank.
+FiniteRankNonAssociativeAlgebra(R:CommutativeRing):
+ Category == NonAssociativeAlgebra R with
+    someBasis : () -> Vector %
+      ++ someBasis() returns some \spad{R}-module basis.
+    rank : () -> PositiveInteger
+      ++ rank() returns the rank of the algebra as \spad{R}-module.
+    conditionsForIdempotents: Vector % -> List Polynomial R
+      ++ conditionsForIdempotents([v1,...,vn]) determines a complete list
+      ++ of polynomial equations for the coefficients of idempotents
+      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+    structuralConstants: Vector % -> Vector Matrix R
+      ++ structuralConstants([v1,v2,...,vm]) calculates the structural
+      ++ constants \spad{[(gammaijk) for k in 1..m]} defined by
+      ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijm * vm},
+      ++ where \spad{[v1,...,vm]} is an \spad{R}-module basis
+      ++ of a subalgebra.
+    leftRegularRepresentation: (% , Vector %) -> Matrix R
+      ++ leftRegularRepresentation(a,[v1,...,vn]) returns the matrix of
+      ++ the linear map defined by left multiplication by \spad{a}
+      ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
+    rightRegularRepresentation: (% , Vector %) -> Matrix R
+      ++ rightRegularRepresentation(a,[v1,...,vn]) returns the matrix of
+      ++ the linear map defined by right multiplication by \spad{a}
+      ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
+    leftTrace: %  -> R
+      ++ leftTrace(a) returns the trace of the left regular representation
+      ++ of \spad{a}.
+    rightTrace: %  -> R
+      ++ rightTrace(a) returns the trace of the right regular representation
+      ++ of \spad{a}.
+    leftNorm: %  -> R
+      ++ leftNorm(a) returns the determinant of the left regular 
+      ++ representation of \spad{a}.
+    rightNorm: %  -> R
+      ++ rightNorm(a) returns the determinant of the right regular
+      ++ representation of \spad{a}.
+    coordinates: (%, Vector %) -> Vector R
+      ++ coordinates(a,[v1,...,vn]) returns the coordinates of \spad{a}
+      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+    coordinates: (Vector %, Vector %) -> Matrix R
+      ++ coordinates([a1,...,am],[v1,...,vn]) returns a matrix whose
+      ++ i-th row is formed by the coordinates of \spad{ai}
+      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+    represents: (Vector R, Vector %) -> %
+      ++ represents([a1,...,am],[v1,...,vm]) returns the linear
+      ++ combination \spad{a1*vm + ... + an*vm}.
+    leftDiscriminant: Vector % -> R
+      ++ leftDiscriminant([v1,...,vn]) returns  the determinant of the
+      ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
+      ++ and \spad{j}-th column is given by the left trace of the product
+      ++ \spad{vi*vj}.
+      ++ Note: the same as \spad{determinant(leftTraceMatrix([v1,...,vn]))}.
+    rightDiscriminant: Vector % -> R
+      ++ rightDiscriminant([v1,...,vn]) returns  the determinant of the
+      ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
+      ++ and \spad{j}-th column is given by the right trace of the product
+      ++ \spad{vi*vj}.
+      ++ Note: the same as \spad{determinant(rightTraceMatrix([v1,...,vn]))}.
+    leftTraceMatrix: Vector % -> Matrix R
+      ++ leftTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
+      ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
+      ++ by the left trace of the product \spad{vi*vj}.
+    rightTraceMatrix: Vector % -> Matrix R
+      ++ rightTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
+      ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
+      ++ by the right trace of the product \spad{vi*vj}.
+    leftCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
+      ++ leftCharacteristicPolynomial(a) returns the characteristic
+      ++ polynomial of the left regular representation of \spad{a}
+      ++ with respect to any basis.
+    rightCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
+      ++ rightCharacteristicPolynomial(a) returns the characteristic
+      ++ polynomial of the right regular representation of \spad{a}
+      ++ with respect to any basis.
+
+    --we not necessarily have a unit
+    --if R has CharacteristicZero then CharacteristicZero
+    --if R has CharacteristicNonZero then CharacteristicNonZero
+
+    commutative?:()-> Boolean
+      ++ commutative?() tests if multiplication in the algebra
+      ++ is commutative.
+    antiCommutative?:()-> Boolean
+      ++ antiCommutative?() tests if \spad{a*a = 0}
+      ++ for all \spad{a} in the algebra.
+      ++ Note: this implies \spad{a*b + b*a = 0} for all 
+      ++ \spad{a} and \spad{b}.
+    associative?:()-> Boolean
+      ++ associative?() tests if multiplication in algebra
+      ++ is associative.
+    antiAssociative?:()-> Boolean
+      ++ antiAssociative?() tests if multiplication in algebra
+      ++ is anti-associative, i.e. \spad{(a*b)*c + a*(b*c) = 0}
+      ++ for all \spad{a},b,c in the algebra.
+    leftAlternative?: ()-> Boolean
+      ++ leftAlternative?() tests if \spad{2*associator(a,a,b) = 0}
+      ++ for all \spad{a}, b in the algebra.
+      ++ Note: we only can test this; in general we don't know
+      ++ whether \spad{2*a=0} implies \spad{a=0}.
+    rightAlternative?: ()-> Boolean
+      ++ rightAlternative?() tests if \spad{2*associator(a,b,b) = 0}
+      ++ for all \spad{a}, b in the algebra.
+      ++ Note: we only can test this; in general we don't know
+      ++ whether \spad{2*a=0} implies \spad{a=0}.
+    flexible?: ()->  Boolean
+      ++ flexible?() tests if \spad{2*associator(a,b,a) = 0}
+      ++ for all \spad{a}, b in the algebra.
+      ++ Note: we only can test this; in general we don't know
+      ++ whether \spad{2*a=0} implies \spad{a=0}.
+    alternative?: ()-> Boolean
+      ++ alternative?() tests if
+      ++ \spad{2*associator(a,a,b) = 0 = 2*associator(a,b,b)}
+      ++ for all \spad{a}, b in the algebra.
+      ++ Note: we only can test this; in general we don't know
+      ++ whether \spad{2*a=0} implies \spad{a=0}.
+    powerAssociative?:()-> Boolean
+      ++ powerAssociative?() tests if all subalgebras
+      ++ generated by a single element are associative.
+    jacobiIdentity?:() -> Boolean
+      ++ jacobiIdentity?() tests if \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
+      ++ for all \spad{a},b,c in the algebra. For example, this holds
+      ++ for crossed products of 3-dimensional vectors.
+    lieAdmissible?: () -> Boolean
+      ++ lieAdmissible?() tests if the algebra defined by the commutators
+      ++ is a Lie algebra, i.e. satisfies the Jacobi identity.
+      ++ The property of anticommutativity follows from definition.
+    jordanAdmissible?: () -> Boolean
+      ++ jordanAdmissible?() tests if 2 is invertible in the
+      ++ coefficient domain and the multiplication defined by
+      ++ \spad{(1/2)(a*b+b*a)} determines a
+      ++ Jordan algebra, i.e. satisfies the Jordan identity.
+      ++ The property of \spadatt{commutative("*")}
+      ++ follows from by definition.
+    noncommutativeJordanAlgebra?: () -> Boolean
+      ++ noncommutativeJordanAlgebra?() tests if the algebra
+      ++ is flexible and Jordan admissible.
+    jordanAlgebra?:() -> Boolean
+      ++ jordanAlgebra?() tests if the algebra is commutative,
+      ++ characteristic is not 2, and \spad{(a*b)*a**2 - a*(b*a**2) = 0}
+      ++ for all \spad{a},b,c in the algebra (Jordan identity).
+      ++ Example:
+      ++ for every associative algebra \spad{(A,+,@)} we can construct a
+      ++ Jordan algebra \spad{(A,+,*)}, where \spad{a*b := (a@b+b@a)/2}.
+    lieAlgebra?:() -> Boolean
+      ++ lieAlgebra?() tests if the algebra is anticommutative
+      ++ and \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
+      ++ for all \spad{a},b,c in the algebra (Jacobi identity).
+      ++ Example:
+      ++ for every associative algebra \spad{(A,+,@)} we can construct a
+      ++ Lie algebra \spad{(A,+,*)}, where \spad{a*b := a@b-b@a}.
+
+    if R has IntegralDomain then
+      -- we not neccessarily have a unit, hence we don't inherit
+      -- the next 3 functions anc hence copy them from MonadWithUnit:
+      recip: % -> Union(%,"failed")
+        ++ recip(a) returns an element, which is both a left and a right
+        ++ inverse of \spad{a},
+        ++ or \spad{"failed"} if there is no unit element, if such an
+        ++ element doesn't exist or cannot be determined (see unitsKnown).
+      leftRecip: % -> Union(%,"failed")
+        ++ leftRecip(a) returns an element, which is a left inverse of 
+        ++ \spad{a}, or \spad{"failed"} if there is no unit element, if such
+        ++ an element doesn't exist or cannot be determined (see unitsKnown).
+      rightRecip: % -> Union(%,"failed")
+        ++ rightRecip(a) returns an element, which is a right inverse of
+        ++ \spad{a},
+        ++ or \spad{"failed"} if there is no unit element, if such an
+        ++ element doesn't exist or cannot be determined (see unitsKnown).
+      associatorDependence:() -> List Vector R
+        ++ associatorDependence() looks for the associator identities, i.e.
+        ++ finds a basis of the solutions of the linear combinations of the
+        ++ six permutations of \spad{associator(a,b,c)} which yield 0,
+        ++ for all \spad{a},b,c in the algebra.
+        ++ The order of the permutations is \spad{123 231 312 132 321 213}.
+      leftMinimalPolynomial : % -> SparseUnivariatePolynomial R
+        ++ leftMinimalPolynomial(a) returns the polynomial determined by the
+        ++ smallest non-trivial linear combination of left powers of 
+        ++ \spad{a}. Note: the polynomial never has a constant term as in 
+        ++ general the algebra has no unit.
+      rightMinimalPolynomial : % -> SparseUnivariatePolynomial R
+        ++ rightMinimalPolynomial(a) returns the polynomial determined by the
+        ++ smallest non-trivial linear
+        ++ combination of right powers of \spad{a}.
+        ++ Note: the polynomial never has a constant term as in general
+        ++ the algebra has no unit.
+      leftUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+        ++ leftUnits() returns the affine space of all left units of the
+        ++ algebra, or \spad{"failed"} if there is none.
+      rightUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+        ++ rightUnits() returns the affine space of all right units of the
+        ++ algebra, or \spad{"failed"} if there is none.
+      leftUnit:() -> Union(%, "failed")
+        ++ leftUnit() returns a left unit of the algebra
+        ++ (not necessarily unique), or \spad{"failed"} if there is none.
+      rightUnit:() -> Union(%, "failed")
+        ++ rightUnit() returns a right unit of the algebra
+        ++ (not necessarily unique), or \spad{"failed"} if there is none.
+      unit:() -> Union(%, "failed")
+        ++ unit() returns a unit of the algebra (necessarily unique),
+        ++ or \spad{"failed"} if there is none.
+      -- we not necessarily have a unit, hence we can't say anything
+      -- about characteristic
+      -- if R has CharacteristicZero then CharacteristicZero
+      -- if R has CharacteristicNonZero then CharacteristicNonZero
+      unitsKnown
+        ++ unitsKnown means that \spadfun{recip} truly yields reciprocal
+        ++ or \spad{"failed"} if not a unit,
+        ++ similarly for \spadfun{leftRecip} and
+        ++ \spadfun{rightRecip}. The reason is that we use left, respectively
+        ++ right, minimal polynomials to decide this question.
+  add
+    --n := rank()
+    --b := someBasis()
+    --gamma : Vector Matrix R := structuralConstants b
+    -- here is a problem: there seems to be a problem having local
+    -- variables in the capsule of a category, furthermore
+    -- see the commented code of conditionsForIdempotents, where
+    -- we call structuralConstants, which also doesn't work
+    -- at runtime, i.e. is not properly inherited, hence for
+    -- the moment we put the code for
+    -- conditionsForIdempotents, structuralConstants, unit, leftUnit,
+    -- rightUnit into the domain constructor ALGSC
+    V  ==> Vector
+    M  ==> Matrix
+    REC  ==> Record(particular: Union(V R,"failed"),basis: List V R)
+    LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+
+
+    SUP ==>  SparseUnivariatePolynomial
+    NNI ==>  NonNegativeInteger
+    -- next 2 functions: use a general characteristicPolynomial
+    leftCharacteristicPolynomial a ==
+       n := rank()$%
+       ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
+       mb : Matrix SUP R := zero(n,n)
+       for i in 1..n repeat
+         for j in 1..n repeat
+           mb(i,j):=
+             i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
+             monomial(ma(i,j),1)$SUP(R)
+       determinant mb
+
+    rightCharacteristicPolynomial a ==
+       n := rank()$%
+       ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
+       mb : Matrix SUP R := zero(n,n)
+       for i in 1..n repeat
+         for j in 1..n repeat
+           mb(i,j):=
+             i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
+             monomial(ma(i,j),1)$SUP(R)
+       determinant mb
+
+    leftTrace a ==
+      t : R := 0
+      ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
+      for i in 1..rank()$% repeat
+        t := t + elt(ma,i,i)
+      t
+
+    rightTrace a ==
+      t : R := 0
+      ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
+      for i in 1..rank()$% repeat
+        t := t + elt(ma,i,i)
+      t
+
+    leftNorm a == determinant leftRegularRepresentation(a,someBasis()$%)
+
+    rightNorm a == determinant rightRegularRepresentation(a,someBasis()$%)
+
+    antiAssociative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+        for j in 1..n repeat
+          for k in 1..n repeat
+            not zero? ( (b.i*b.j)*b.k + b.i*(b.j*b.k) )  =>
+              messagePrint("algebra is not anti-associative")$OutputForm
+              return false
+      messagePrint("algebra is anti-associative")$OutputForm
+      true
+
+    jordanAdmissible?() ==
+      b := someBasis()
+      n := rank()
+      recip(2 * 1$R) case "failed" =>
+        messagePrint("this algebra is not Jordan admissible, " _
+         "as 2 is not invertible in the ground ring")$OutputForm
+        false
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         for l in 1..n repeat
+           not zero? ( _
+             antiCommutator(antiCommutator(b.i,b.j),_
+                            antiCommutator(b.l,b.k)) + _
+             antiCommutator(antiCommutator(b.l,b.j),_
+                            antiCommutator(b.k,b.i)) + _
+             antiCommutator(antiCommutator(b.k,b.j),_
+                            antiCommutator(b.i,b.l))   _
+                      ) =>
+               messagePrint(_
+                         "this algebra is not Jordan admissible")$OutputForm
+               return false
+      messagePrint("this algebra is Jordan admissible")$OutputForm
+      true
+
+    lieAdmissible?() ==
+      n := rank()
+      b := someBasis()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+          not zero? (commutator(commutator(b.i,b.j),b.k) _
+                  + commutator(commutator(b.j,b.k),b.i) _
+                  + commutator(commutator(b.k,b.i),b.j))   =>
+            messagePrint("this algebra is not Lie admissible")$OutputForm
+            return false
+      messagePrint("this algebra is Lie admissible")$OutputForm
+      true
+
+    -- conditionsForIdempotents b  ==
+    --   n := rank()
+    --   gamma : Vector Matrix R := structuralConstants b
+    --   listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
+    --   symbolsForCoef : Vector Symbol :=
+    --     [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
+    --   conditions : List Polynomial R := []
+    --  for k in 1..n repeat
+    --    xk := symbolsForCoef.k
+    --    p : Polynomial R :=  monomial( - 1$Polynomial(R), [xk], [1] )
+    --    for i in 1..n repeat
+    --      for j in 1..n repeat
+    --        xi := symbolsForCoef.i
+    --        xj := symbolsForCoef.j
+    --        p := p + monomial(_
+    --          elt((gamma.k),i,j) :: Polynomial(R), [xi,xj], [1,1])
+    --    conditions := cons(p,conditions)
+    --  conditions
+
+    structuralConstants b ==
+      --n := rank()
+      -- be careful with the possibility that b is not a basis
+      m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
+      sC : Vector Matrix R := [new(m,m,0$R) for k in 1..m]
+      for i in 1..m repeat
+        for j in 1..m repeat
+          covec : Vector R := coordinates(b.i * b.j, b)
+          for k in 1..m repeat
+             setelt( sC.k, i, j, covec.k )
+      sC
+
+    if R has IntegralDomain then
+
+      leftRecip x ==
+        zero? x => "failed"
+        lu := leftUnit()
+        lu case "failed" => "failed"
+        b := someBasis()
+        xx : % := (lu :: %)
+        k  : PositiveInteger := 1
+        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+        listOfPowers : List % := [xx]
+        while rank(cond) = k repeat
+          k := k+1
+          xx := xx*x
+          listOfPowers := cons(xx,listOfPowers)
+          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+        invC := recip vectorOfCoef.1
+        invC case "failed" => "failed"
+        invCR : R :=  - (invC :: R)
+        reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
+         2..maxIndex vectorOfCoef for power in reverse listOfPowers])
+
+      rightRecip x ==
+        zero? x => "failed"
+        ru := rightUnit()
+        ru case "failed" => "failed"
+        b := someBasis()
+        xx : % := (ru :: %)
+        k  : PositiveInteger := 1
+        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+        listOfPowers : List % := [xx]
+        while rank(cond) = k repeat
+          k := k+1
+          xx := x*xx
+          listOfPowers := cons(xx,listOfPowers)
+          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+        invC := recip vectorOfCoef.1
+        invC case "failed" => "failed"
+        invCR : R :=  - (invC :: R)
+        reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
+         2..maxIndex vectorOfCoef for power in reverse listOfPowers])
+
+      recip x ==
+        lrx := leftRecip x
+        lrx case "failed" => "failed"
+        rrx := rightRecip x
+        rrx case "failed" => "failed"
+        (lrx :: %) ^= (rrx :: %)  => "failed"
+        lrx :: %
+
+      leftMinimalPolynomial x ==
+        zero? x =>  monomial(1$R,1)$(SparseUnivariatePolynomial R)
+        b := someBasis()
+        xx : % := x
+        k  : PositiveInteger := 1
+        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+        while rank(cond) = k repeat
+          k := k+1
+          xx := x*xx
+          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+        res : SparseUnivariatePolynomial R := 0
+        for i in 1..k repeat
+          res:=res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
+        res
+
+      rightMinimalPolynomial x ==
+        zero? x =>  monomial(1$R,1)$(SparseUnivariatePolynomial R)
+        b := someBasis()
+        xx : % := x
+        k  : PositiveInteger := 1
+        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+        while rank(cond) = k repeat
+          k := k+1
+          xx := xx*x
+          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+        res : SparseUnivariatePolynomial R := 0
+        for i in 1..k repeat
+          res:=res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
+        res
+
+      associatorDependence() ==
+        n := rank()
+        b := someBasis()
+        cond : Matrix(R) := new(n**4,6,0$R)$Matrix(R)
+        z : Integer := 0
+        for i in 1..n repeat
+         for j in 1..n repeat
+          for k in 1..n repeat
+           a123 : Vector R := coordinates(associator(b.i,b.j,b.k),b)
+           a231 : Vector R := coordinates(associator(b.j,b.k,b.i),b)
+           a312 : Vector R := coordinates(associator(b.k,b.i,b.j),b)
+           a132 : Vector R := coordinates(associator(b.i,b.k,b.j),b)
+           a321 : Vector R := coordinates(associator(b.k,b.j,b.i),b)
+           a213 : Vector R := coordinates(associator(b.j,b.i,b.k),b)
+           for r in 1..n repeat
+            z:= z+1
+            setelt(cond,z,1,elt(a123,r))
+            setelt(cond,z,2,elt(a231,r))
+            setelt(cond,z,3,elt(a312,r))
+            setelt(cond,z,4,elt(a132,r))
+            setelt(cond,z,5,elt(a321,r))
+            setelt(cond,z,6,elt(a213,r))
+        nullSpace(cond)
+
+    jacobiIdentity?()  ==
+      n := rank()
+      b := someBasis()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+          not zero? ((b.i*b.j)*b.k + (b.j*b.k)*b.i + (b.k*b.i)*b.j) =>
+            messagePrint("Jacobi identity does not hold")$OutputForm
+            return false
+      messagePrint("Jacobi identity holds")$OutputForm
+      true
+
+    lieAlgebra?()  ==
+      not antiCommutative?() =>
+        messagePrint("this is not a Lie algebra")$OutputForm
+        false
+      not jacobiIdentity?() =>
+        messagePrint("this is not a Lie algebra")$OutputForm
+        false
+      messagePrint("this is a Lie algebra")$OutputForm
+      true
+
+    jordanAlgebra?()  ==
+      b := someBasis()
+      n := rank()
+      recip(2 * 1$R) case "failed" =>
+        messagePrint("this is not a Jordan algebra, as 2 is not " _
+         "invertible in the ground ring")$OutputForm
+        false
+      not commutative?() =>
+        messagePrint("this is not a Jordan algebra")$OutputForm
+        false
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         for l in 1..n repeat
+           not zero? (associator(b.i,b.j,b.l*b.k)+_
+               associator(b.l,b.j,b.k*b.i)+associator(b.k,b.j,b.i*b.l)) =>
+             messagePrint("not a Jordan algebra")$OutputForm
+             return false
+      messagePrint("this is a Jordan algebra")$OutputForm
+      true
+
+    noncommutativeJordanAlgebra?() ==
+      b := someBasis()
+      n := rank()
+      recip(2 * 1$R) case "failed" =>                             
+       messagePrint("this is not a noncommutative Jordan algebra,")$OutputForm
+       messagePrint(" as 2 is not invertible in the ground ring")$OutputForm
+       false
+      not flexible?()$% =>
+       messagePrint("this is not a noncommutative Jordan algebra,")$OutputForm
+       messagePrint(" as it is not flexible")$OutputForm
+       false
+      not jordanAdmissible?()$% =>
+       messagePrint("this is not a noncommutative Jordan algebra,")$OutputForm
+       messagePrint(" as it is not Jordan admissible")$OutputForm
+       false
+      messagePrint("this is a noncommutative Jordan algebra")$OutputForm
+      true
+
+    antiCommutative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+        for j in i..n repeat
+          not zero? (i=j => b.i*b.i; b.i*b.j + b.j*b.i) =>
+            messagePrint("algebra is not anti-commutative")$OutputForm
+            return false
+      messagePrint("algebra is anti-commutative")$OutputForm
+      true
+
+    commutative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in i+1..n repeat
+         not zero? commutator(b.i,b.j) =>
+           messagePrint("algebra is not commutative")$OutputForm
+           return false
+      messagePrint("algebra is commutative")$OutputForm
+      true
+
+    associative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         not zero? associator(b.i,b.j,b.k) =>
+           messagePrint("algebra is not associative")$OutputForm
+           return false
+      messagePrint("algebra is associative")$OutputForm
+      true
+
+    leftAlternative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
+           messagePrint("algebra is not left alternative")$OutputForm
+           return false
+      messagePrint("algebra satisfies 2*associator(a,a,b) = 0")$OutputForm
+      true
+
+    rightAlternative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
+           messagePrint("algebra is not right alternative")$OutputForm
+           return false
+      messagePrint("algebra satisfies 2*associator(a,b,b) = 0")$OutputForm
+      true
+
+    flexible?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         not zero? (associator(b.i,b.j,b.k) + associator(b.k,b.j,b.i)) =>
+           messagePrint("algebra is not flexible")$OutputForm
+           return false
+      messagePrint("algebra satisfies 2*associator(a,b,a) = 0")$OutputForm
+      true
+
+    alternative?() ==
+      b := someBasis()
+      n := rank()
+      for i in 1..n repeat
+       for j in 1..n repeat
+        for k in 1..n repeat
+         not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
+           messagePrint("algebra is not alternative")$OutputForm
+           return false
+         not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
+           messagePrint("algebra is not alternative")$OutputForm
+           return false
+      messagePrint("algebra satisfies 2*associator(a,b,b) = 0 " _
+                   "=  2*associator(a,a,b) = 0")$OutputForm
+      true
+
+    leftDiscriminant v == determinant leftTraceMatrix v
+    rightDiscriminant v == determinant rightTraceMatrix v
+
+    coordinates(v:Vector %, b:Vector %) ==
+      m := new(#v, #b, 0)$Matrix(R)
+      for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+        setRow_!(m, j, coordinates(qelt(v, i), b))
+      m
+
+    represents(v, b) ==
+      m := minIndex v - 1
+      reduce(_+,[v(i+m) * b(i+m) for i in 1..maxIndex b])
+
+    leftTraceMatrix v ==
+      matrix [[leftTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
+               for i in minIndex v .. maxIndex v]$List(List R)
+
+    rightTraceMatrix v ==
+      matrix [[rightTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
+               for i in minIndex v .. maxIndex v]$List(List R)
+
+    leftRegularRepresentation(x, b) ==
+      m := minIndex b - 1
+      matrix
+       [parts coordinates(x*b(i+m),b) for i in 1..rank()]$List(List R)
+
+    rightRegularRepresentation(x, b) ==
+      m := minIndex b - 1
+      matrix
+       [parts coordinates(b(i+m)*x,b) for i in 1..rank()]$List(List R)
+
+@
+<<FINAALG.dotabb>>=
+"FINAALG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FINAALG"];
+"FINAALG" -> "NAALG"
+
+@
+<<FINAALG.dotfull>>=
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FINAALG"];
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)" ->
+    "NonAssociativeAlgebra(a:CommutativeRing)"
+
+@
+<<FINAALG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)" ->
+    "NonAssociativeAlgebra(a:CommutativeRing)"
+
+"NonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "ABELGRP..."
+"NonAssociativeRng()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
+
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+}
+
+@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{IntegralDomain}{INTDOM}
 \pagepic{ps/v102integraldomain.ps}{INTDOM}{0.65}
 
@@ -16465,6 +18451,586 @@ digraph pic {
 @
 \chapter{Category Layer 13}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{FramedNonAssociativeAlgebra}{FRNAALG}
+\pagepic{ps/v102framednonassociativealgebra.ps}{FRNAALG}{0.65}
+
+{\bf See:}\\
+\pagefrom{FiniteRankNonAssociativeAlgebra}{FINAALG}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{FRNAALG}{0} &
+\cross{FRNAALG}{alternative?} \\
+\cross{FRNAALG}{antiAssociative?} &
+\cross{FRNAALG}{antiCommutative?} \\
+\cross{FRNAALG}{antiCommutator} &
+\cross{FRNAALG}{apply} \\
+\cross{FRNAALG}{associative?} &
+\cross{FRNAALG}{associator} \\
+\cross{FRNAALG}{associatorDependence} &
+\cross{FRNAALG}{basis} \\
+\cross{FRNAALG}{coerce} &
+\cross{FRNAALG}{commutative?} \\
+\cross{FRNAALG}{commutator} &
+\cross{FRNAALG}{conditionsForIdempotents} \\
+\cross{FRNAALG}{convert} &
+\cross{FRNAALG}{coordinates} \\
+\cross{FRNAALG}{flexible?} &
+\cross{FRNAALG}{hash} \\
+\cross{FRNAALG}{jacobiIdentity?} &
+\cross{FRNAALG}{jordanAdmissible?} \\
+\cross{FRNAALG}{jordanAlgebra?} &
+\cross{FRNAALG}{latex} \\
+\cross{FRNAALG}{leftAlternative?} &
+\cross{FRNAALG}{leftCharacteristicPolynomial} \\
+\cross{FRNAALG}{leftDiscriminant} &
+\cross{FRNAALG}{leftMinimalPolynomial} \\
+\cross{FRNAALG}{leftNorm} &
+\cross{FRNAALG}{leftPower} \\
+\cross{FRNAALG}{leftRankPolynomial} &
+\cross{FRNAALG}{leftRecip} \\
+\cross{FRNAALG}{leftRegularRepresentation} &
+\cross{FRNAALG}{leftTrace} \\
+\cross{FRNAALG}{leftTraceMatrix} &
+\cross{FRNAALG}{leftUnit} \\
+\cross{FRNAALG}{leftUnits} &
+\cross{FRNAALG}{lieAdmissible?} \\
+\cross{FRNAALG}{lieAlgebra?} &
+\cross{FRNAALG}{noncommutativeJordanAlgebra?} \\
+\cross{FRNAALG}{plenaryPower} &
+\cross{FRNAALG}{powerAssociative?} \\
+\cross{FRNAALG}{rank} &
+\cross{FRNAALG}{recip} \\
+\cross{FRNAALG}{represents} &
+\cross{FRNAALG}{rightAlternative?} \\
+\cross{FRNAALG}{rightCharacteristicPolynomial} &
+\cross{FRNAALG}{rightDiscriminant} \\
+\cross{FRNAALG}{rightMinimalPolynomial} &
+\cross{FRNAALG}{rightNorm} \\
+\cross{FRNAALG}{rightPower} &
+\cross{FRNAALG}{rightRankPolynomial} \\
+\cross{FRNAALG}{rightRecip} &
+\cross{FRNAALG}{rightRegularRepresentation} \\
+\cross{FRNAALG}{rightTrace} &
+\cross{FRNAALG}{rightTraceMatrix} \\
+\cross{FRNAALG}{rightUnit} &
+\cross{FRNAALG}{rightUnits} \\
+\cross{FRNAALG}{sample} &
+\cross{FRNAALG}{someBasis} \\
+\cross{FRNAALG}{structuralConstants} &
+\cross{FRNAALG}{subtractIfCan} \\
+\cross{FRNAALG}{unit} &
+\cross{FRNAALG}{zero?} \\
+\cross{FRNAALG}{?*?} &
+\cross{FRNAALG}{?**?} \\
+\cross{FRNAALG}{?+?} &
+\cross{FRNAALG}{?-?} \\
+\cross{FRNAALG}{-?} &
+\cross{FRNAALG}{?=?} \\
+\cross{FRNAALG}{?.?} &
+\cross{FRNAALG}{?~=?} \\
+\end{tabular}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ apply : (Matrix R,%) -> %
+ basis : () -> Vector %               
+ convert : Vector R -> %              
+ ?.? : (%,Integer) -> R
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ conditionsForIdempotents : () -> List Polynomial R
+ convert : % -> Vector R
+ coordinates : % -> Vector R          
+ coordinates : Vector % -> Matrix R
+ leftDiscriminant : () -> R
+ leftRankPolynomial : () -> 
+   SparseUnivariatePolynomial Polynomial R 
+     if R has FIELD
+ leftRegularRepresentation : % -> Matrix R
+ leftTraceMatrix : () -> Matrix R
+ leftUnit : () -> Union(%,"failed") if R has INTDOM
+ leftUnits : () -> 
+   Union(Record(particular: %,basis: List %),"failed") 
+     if R has INTDOM
+ represents : Vector R -> %           
+ rightDiscriminant : () -> R          
+ rightRankPolynomial : () -> 
+   SparseUnivariatePolynomial Polynomial R 
+     if R has FIELD
+ rightRegularRepresentation : % -> Matrix R
+ rightTraceMatrix : () -> Matrix R    
+ rightUnit : () -> Union(%,"failed") if R has INTDOM
+ rightUnits : () -> 
+   Union(Record(particular: %,basis: List %),"failed") 
+     if R has INTDOM
+ structuralConstants : () -> Vector Matrix R
+ unit : () -> Union(%,"failed") if R has INTDOM
+\end{verbatim}
+
+These exports come from FiniteRankNonAssociativeAlgebra(R)\\
+where R:CommutativeRing:
+\begin{verbatim}
+ 0 : () -> %                          
+ alternative? : () -> Boolean
+ antiAssociative? : () -> Boolean     
+ antiCommutative? : () -> Boolean
+ antiCommutator : (%,%) -> %          
+ associative? : () -> Boolean         
+ associator : (%,%,%) -> %
+ associatorDependence : () -> List Vector R 
+     if R has INTDOM
+ coerce : % -> OutputForm
+ commutative? : () -> Boolean         
+ commutator : (%,%) -> %
+ conditionsForIdempotents : Vector % -> List Polynomial R
+ coordinates : (Vector %,Vector %) -> Matrix R
+ coordinates : (%,Vector %) -> Vector R
+ flexible? : () -> Boolean            
+ hash : % -> SingleInteger
+ jacobiIdentity? : () -> Boolean      
+ jordanAdmissible? : () -> Boolean
+ jordanAlgebra? : () -> Boolean       
+ latex : % -> String
+ leftAlternative? : () -> Boolean     
+ leftCharacteristicPolynomial : % -> 
+   SparseUnivariatePolynomial R
+ leftDiscriminant : Vector % -> R     
+ leftMinimalPolynomial : % -> 
+   SparseUnivariatePolynomial R 
+     if R has INTDOM
+ leftNorm : % -> R
+ leftPower : (%,PositiveInteger) -> %
+ leftRecip : % -> Union(%,"failed") if R has INTDOM
+ leftRegularRepresentation : (%,Vector %) -> Matrix R
+ leftTrace : % -> R                   
+ leftTraceMatrix : Vector % -> Matrix R
+ lieAdmissible? : () -> Boolean       
+ lieAlgebra? : () -> Boolean
+ noncommutativeJordanAlgebra? : () -> Boolean
+ plenaryPower : (%,PositiveInteger) -> %
+ powerAssociative? : () -> Boolean    
+ rank : () -> PositiveInteger
+ recip : % -> Union(%,"failed") if R has INTDOM
+ represents : (Vector R,Vector %) -> %
+ rightAlternative? : () -> Boolean
+ rightCharacteristicPolynomial : % -> 
+   SparseUnivariatePolynomial R
+ rightDiscriminant : Vector % -> R
+ rightMinimalPolynomial : % -> 
+   SparseUnivariatePolynomial R 
+     if R has INTDOM
+ rightNorm : % -> R                   
+ rightPower : (%,PositiveInteger) -> %
+ rightRecip : % -> Union(%,"failed") if R has INTDOM
+ rightRegularRepresentation : (%,Vector %) -> Matrix R
+ rightTrace : % -> R
+ rightTraceMatrix : Vector % -> Matrix R
+ sample : () -> %
+ someBasis : () -> Vector %           
+ structuralConstants : Vector % -> Vector Matrix R
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ zero? : % -> Boolean
+ ?~=? : (%,%) -> Boolean              
+ ?*? : (PositiveInteger,%) -> %       
+ ?*? : (%,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?*? : (NonNegativeInteger,%) -> %
+ ?*? : (R,%) -> %                     
+ ?*? : (%,R) -> %
+ ?+? : (%,%) -> %                     
+ ?=? : (%,%) -> Boolean
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?**? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+<<category FRNAALG FramedNonAssociativeAlgebra>>=
+)abbrev category FRNAALG FramedNonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +,-,*,**,basis
+++ Related Constructors: FiniteRankNonAssociativeAlgebra, FramedAlgebra,
+++   FiniteRankAssociativeAlgebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra, basis
+++ Reference:
+++  R.D. Schafer: An Introduction to Nonassociative Algebras
+++  Academic Press, New York, 1966
+++ Description:
+++   FramedNonAssociativeAlgebra(R) is a
+++   \spadtype{FiniteRankNonAssociativeAlgebra} (i.e. a non associative
+++   algebra over R which is a free \spad{R}-module of finite rank)
+++   over a commutative ring R together with a fixed \spad{R}-module basis.
+FramedNonAssociativeAlgebra(R:CommutativeRing):
+        Category == FiniteRankNonAssociativeAlgebra(R) with
+    basis: () -> Vector %
+      ++ basis() returns the fixed \spad{R}-module basis.
+    coordinates: % -> Vector R
+      ++ coordinates(a) returns the coordinates of \spad{a}
+      ++ with respect to the
+      ++ fixed \spad{R}-module basis.
+    coordinates: Vector % -> Matrix R
+      ++ coordinates([a1,...,am]) returns a matrix whose i-th row
+      ++ is formed by the coordinates of \spad{ai} with respect to the
+      ++ fixed \spad{R}-module basis.
+    elt : (%,Integer) -> R
+      ++ elt(a,i) returns the i-th coefficient of \spad{a} with respect 
+      ++ to the fixed \spad{R}-module basis.
+    structuralConstants:() -> Vector Matrix R
+      ++ structuralConstants() calculates the structural constants
+      ++ \spad{[(gammaijk) for k in 1..rank()]} defined by
+      ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijn * vn},
+      ++ where \spad{v1},...,\spad{vn} is the fixed \spad{R}-module basis.
+    conditionsForIdempotents: () -> List Polynomial R
+      ++ conditionsForIdempotents() determines a complete list
+      ++ of polynomial equations for the coefficients of idempotents
+      ++ with respect to the fixed \spad{R}-module basis.
+    represents: Vector R -> %
+      ++ represents([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
+      ++ where \spad{v1}, ..., \spad{vn} are the elements of the
+      ++ fixed \spad{R}-module basis.
+    convert: % -> Vector R
+      ++ convert(a) returns the coordinates of \spad{a} with respect to the
+      ++ fixed \spad{R}-module basis.
+    convert: Vector R -> %
+      ++ convert([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
+      ++ where \spad{v1}, ..., \spad{vn} are the elements of the
+      ++ fixed \spad{R}-module basis.
+    leftDiscriminant : () -> R
+      ++ leftDiscriminant() returns the
+      ++ determinant of the \spad{n}-by-\spad{n}
+      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column
+      ++ is given by the left trace of the product \spad{vi*vj}, where
+      ++ \spad{v1},...,\spad{vn} are the
+      ++ elements of the fixed \spad{R}-module basis.
+      ++ Note: the same as \spad{determinant(leftTraceMatrix())}.
+    rightDiscriminant : () -> R
+      ++ rightDiscriminant() returns the determinant of the 
+      ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row 
+      ++ and \spad{j}-th column is 
+      ++ given by the right trace of the product \spad{vi*vj}, where
+      ++ \spad{v1},...,\spad{vn} are the elements of
+      ++ the fixed \spad{R}-module basis.
+      ++ Note: the same as \spad{determinant(rightTraceMatrix())}.
+    leftTraceMatrix : () -> Matrix R
+      ++ leftTraceMatrix() is the \spad{n}-by-\spad{n}
+      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column
+      ++ is given by left trace of the product \spad{vi*vj},
+      ++ where \spad{v1},...,\spad{vn} are the
+      ++ elements of the fixed \spad{R}-module basis.
+    rightTraceMatrix : () -> Matrix R
+      ++ rightTraceMatrix() is the \spad{n}-by-\spad{n}
+      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column
+      ++ is given by the right trace of the product \spad{vi*vj}, where
+      ++ \spad{v1},...,\spad{vn} are the elements
+      ++ of the fixed \spad{R}-module basis.
+    leftRegularRepresentation : % -> Matrix R
+      ++ leftRegularRepresentation(a) returns the matrix of the linear
+      ++ map defined by left multiplication by \spad{a} with respect
+      ++ to the fixed \spad{R}-module basis.
+    rightRegularRepresentation : % -> Matrix R
+      ++ rightRegularRepresentation(a) returns the matrix of the linear
+      ++ map defined by right multiplication by \spad{a} with respect
+      ++ to the fixed \spad{R}-module basis.
+    if R has Field then
+      leftRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
+        ++ leftRankPolynomial() calculates the left minimal polynomial
+        ++ of the generic element in the algebra,
+        ++ defined by the same structural
+        ++ constants over the polynomial ring in symbolic coefficients with
+        ++ respect to the fixed basis.
+      rightRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
+        ++ rightRankPolynomial() calculates the right minimal polynomial
+        ++ of the generic element in the algebra,
+        ++ defined by the same structural
+        ++ constants over the polynomial ring in symbolic coefficients with
+        ++ respect to the fixed basis.
+    apply: (Matrix R, %) -> %
+      ++ apply(m,a) defines a left operation of n by n matrices
+      ++ where n is the rank of the algebra in terms of matrix-vector
+      ++ multiplication, this is a substitute for a left module structure.
+      ++ Error: if shape of matrix doesn't fit.
+    --attributes
+      --separable <=> discriminant() ^= 0
+  add
+
+    V  ==> Vector
+    M  ==> Matrix
+    P  ==> Polynomial
+    F  ==> Fraction
+    REC  ==> Record(particular: Union(V R,"failed"),basis: List V R)
+    LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+    CVMP ==> CoerceVectorMatrixPackage(R)
+
+    --GA ==> GenericNonAssociativeAlgebra(R,rank()$%,_
+    -- [random()$Character :: String :: Symbol for i in 1..rank()$%], _
+    -- structuralConstants()$%)
+    --y : GA := generic()
+    if R has Field then
+      leftRankPolynomial() ==
+        n := rank()
+        b := basis()
+        gamma : Vector Matrix R := structuralConstants b
+        listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
+        symbolsForCoef : Vector Symbol :=
+          [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
+        xx : M P R
+        mo : P R
+        x : M P R := new(1,n,0)
+        for i in 1..n repeat
+          mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
+          qsetelt_!(x,1,i,mo)
+        y : M P R := copy x
+        k  : PositiveInteger := 1
+        cond : M P R := copy x
+        -- multiplication in the generic algebra means using
+        -- the structural matrices as bilinear forms.
+        -- left multiplication by x, we prepare for that:
+        genGamma : V M P R :=  coerceP$CVMP gamma
+        x := reduce(horizConcat,[x*genGamma(i) for i in 1..#genGamma])
+        while rank(cond) = k repeat
+          k := k+1
+          for i in 1..n repeat
+            setelt(xx,[1],[i],x*transpose y)
+          y := copy xx
+          cond := horizConcat(cond, xx)
+        vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
+        res : SparseUnivariatePolynomial P R := 0
+        for i in 1..k repeat
+         res:=res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial P R)
+        res
+
+      rightRankPolynomial() ==
+        n := rank()
+        b := basis()
+        gamma : Vector Matrix R := structuralConstants b
+        listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
+        symbolsForCoef : Vector Symbol :=
+          [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
+        xx : M P R
+        mo : P R
+        x : M P R := new(1,n,0)
+        for i in 1..n repeat
+          mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
+          qsetelt_!(x,1,i,mo)
+        y : M P R := copy x
+        k  : PositiveInteger := 1
+        cond : M P R := copy x
+        -- multiplication in the generic algebra means using
+        -- the structural matrices as bilinear forms.
+        -- left multiplication by x, we prepare for that:
+        genGamma : V M P R :=  coerceP$CVMP gamma
+        x := _
+         reduce(horizConcat,[genGamma(i)*transpose x for i in 1..#genGamma])
+        while rank(cond) = k repeat
+          k := k+1
+          for i in 1..n repeat
+            setelt(xx,[1],[i],y * transpose x)
+          y := copy xx
+          cond := horizConcat(cond, xx)
+        vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
+        res : SparseUnivariatePolynomial P R := 0
+        for i in 1..k repeat
+         res := _
+          res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial  P R)
+        res
+
+      leftUnitsInternal : () -> REC
+      leftUnitsInternal() ==
+        n := rank()
+        b := basis()
+        gamma : Vector Matrix R := structuralConstants b
+        cond : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
+        rhs : Vector(R) := new(n**2,0$R)$Vector(R)
+        z : Integer := 0
+        addOn : R := 0
+        for k in 1..n repeat
+         for i in 1..n repeat
+           z := z+1   -- index for the rows
+           addOn :=
+             k=i => 1
+             0
+           setelt(rhs,z,addOn)$Vector(R)
+           for j in 1..n repeat  -- index for the columns
+             setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
+        solve(cond,rhs)$LSMP
+
+
+      leftUnit() ==
+        res : REC := leftUnitsInternal()
+        res.particular case "failed" =>
+          messagePrint("this algebra has no left unit")$OutputForm
+          "failed"
+        represents (res.particular :: V R)
+
+      leftUnits() ==
+        res : REC := leftUnitsInternal()
+        res.particular case "failed" =>
+          messagePrint("this algebra has no left unit")$OutputForm
+          "failed"
+        [represents(res.particular :: V R)$%, _
+          map(represents, res.basis)$ListFunctions2(Vector R, %) ]
+
+      rightUnitsInternal : () -> REC
+      rightUnitsInternal() ==
+        n := rank()
+        b := basis()
+        gamma : Vector Matrix R := structuralConstants b
+        condo : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
+        rhs : Vector(R) := new(n**2,0$R)$Vector(R)
+        z : Integer := 0
+        addOn : R := 0
+        for k in 1..n repeat
+         for i in 1..n repeat
+           z := z+1   -- index for the rows
+           addOn :=
+             k=i => 1
+             0
+           setelt(rhs,z,addOn)$Vector(R)
+           for j in 1..n repeat  -- index for the columns
+             setelt(condo,z,j,elt(gamma.k,i,j))$Matrix(R)
+        solve(condo,rhs)$LSMP
+
+      rightUnit() ==
+        res : REC := rightUnitsInternal()
+        res.particular case "failed" =>
+          messagePrint("this algebra has no right unit")$OutputForm
+          "failed"
+        represents (res.particular :: V R)
+
+      rightUnits() ==
+        res : REC := rightUnitsInternal()
+        res.particular case "failed" =>
+          messagePrint("this algebra has no right unit")$OutputForm
+          "failed"
+        [represents(res.particular :: V R)$%, _
+          map(represents, res.basis)$ListFunctions2(Vector R, %) ]
+
+      unit() ==
+        n := rank()
+        b := basis()
+        gamma : Vector Matrix R := structuralConstants b
+        cond : Matrix(R) := new(2*n**2,n,0$R)$Matrix(R)
+        rhs : Vector(R) := new(2*n**2,0$R)$Vector(R)
+        z : Integer := 0
+        u : Integer := n*n
+        addOn : R := 0
+        for k in 1..n repeat
+         for i in 1..n repeat
+           z := z+1   -- index for the rows
+           addOn :=
+             k=i => 1
+             0
+           setelt(rhs,z,addOn)$Vector(R)
+           setelt(rhs,u,addOn)$Vector(R)
+           for j in 1..n repeat  -- index for the columns
+             setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
+             setelt(cond,u,j,elt(gamma.k,i,j))$Matrix(R)
+        res : REC := solve(cond,rhs)$LSMP
+        res.particular case "failed" =>
+          messagePrint("this algebra has no unit")$OutputForm
+          "failed"
+        represents (res.particular :: V R)
+    apply(m:Matrix(R),a:%) ==
+      v : Vector R := coordinates(a)
+      v := m *$Matrix(R) v
+      convert v
+
+
+    structuralConstants()   == structuralConstants basis()
+    conditionsForIdempotents() == conditionsForIdempotents basis()
+    convert(x:%):Vector(R)  == coordinates(x, basis())
+    convert(v:Vector R):%   == represents(v, basis())
+    leftTraceMatrix()       == leftTraceMatrix basis()
+    rightTraceMatrix()      == rightTraceMatrix basis()
+    leftDiscriminant()      == leftDiscriminant basis()
+    rightDiscriminant()     == rightDiscriminant basis()
+    leftRegularRepresentation x == leftRegularRepresentation(x, basis())
+    rightRegularRepresentation x == rightRegularRepresentation(x, basis())
+    coordinates x           == coordinates(x, basis())
+    represents(v:Vector R):%== represents(v, basis())
+
+    coordinates(v:Vector %) ==
+      m := new(#v, rank(), 0)$Matrix(R)
+      for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+        setRow_!(m, j, coordinates qelt(v, i))
+      m
+
+@
+<<FRNAALG.dotabb>>=
+"FRNAALG"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FRNAALG"];
+"FRNAALG" -> "FINAALG"
+
+@
+<<FRNAALG.dotfull>>=
+"FramedNonAssociativeAlgebra(a:CommutativeRing)"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FRNAALG"];
+"FramedNonAssociativeAlgebra(a:CommutativeRing)" ->
+    "FiniteRankNonAssociativeAlgebra(a:CommutativeRing)"
+
+@
+<<FRNAALG.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"FramedNonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"FramedNonAssociativeAlgebra(a:CommutativeRing)" ->
+    "FiniteRankNonAssociativeAlgebra(a:CommutativeRing)"
+
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"FiniteRankNonAssociativeAlgebra(a:CommutativeRing)" ->
+    "NonAssociativeAlgebra(a:CommutativeRing)"
+
+"NonAssociativeAlgebra(a:CommutativeRing)" [color=lightblue];
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "NonAssociativeRng()"
+"NonAssociativeAlgebra(a:CommutativeRing)" -> "Module(a:CommutativeRing)"
+
+"NonAssociativeRng()" [color=lightblue];
+"NonAssociativeRng()" -> "ABELGRP..."
+"NonAssociativeRng()" -> "Monad()"
+
+"Monad()" [color=lightblue];
+"Monad()" -> "SETCAT..."
+"Monad()" -> "REPSQ..."
+
+"Module(a:CommutativeRing)" [color=lightblue];
+"Module(a:CommutativeRing)" ->
+  "BiModule(a:CommutativeRing,b:CommutativeRing)"
+
+"BiModule(a:CommutativeRing,b:CommutativeRing)" [color=seagreen];
+"BiModule(a:CommutativeRing,b:CommutativeRing)" -> "BiModule(a:Ring,b:Ring)"
+
+"BiModule(a:Ring,b:Ring)" [color=lightblue];
+"BiModule(a:Ring,b:Ring)" -> "LeftModule(a:Ring)"
+"BiModule(a:Ring,b:Ring)" -> "RightModule(a:Ring)"
+
+"RightModule(a:Ring)" [color=seagreen];
+"RightModule(a:Ring)" -> "RightModule(a:Rng)"
+
+"RightModule(a:Rng)" [color=lightblue];
+"RightModule(a:Rng)" -> "ABELGRP..."
+
+"LeftModule(a:Ring)" [color=seagreen];
+"LeftModule(a:Ring)" -> "LeftModule(a:Rng)"
+
+"LeftModule(a:Rng)" [color=lightblue];
+"LeftModule(a:Rng)" -> "ABELGRP..."
+
+"REPSQ..." [color="#00EE00"];
+"SETCAT..." [color=lightblue];
+"ABELGRP..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{GcdDomain}{GCDDOM}
 \pagepic{ps/v102gcddomain.ps}{GCDDOM}{0.65}
 
@@ -16623,7 +19189,6 @@ GcdDomain(): Category == IntegralDomain with
 @
 <<GCDDOM.dotabb>>=
 "GCDDOM"
- [color=lightblue,href="bookvol10.2.pdf#nameddest=GCDDOM"];
 "GCDDOM" -> "INTDOM"
 
 @
@@ -18256,6 +20821,7 @@ digraph pic {
 \pagepic{ps/v102monogenicalgebra.ps}{MONOGEN}{0.70}
 
 {\bf See:}\\
+\pageto{FunctionFieldCategory}{FFCAT}
 \pagefrom{CommutativeRing}{COMRING}
 \pagefrom{ConvertibleTo}{KONVERT}
 \pagefrom{FramedAlgebra}{FRAMALG}
@@ -18393,9 +20959,973 @@ digraph pic {
 "FRETRCT..." [color=lightblue];
 "FLINEXP..." [color=lightblue];
 }
+
 @
 \chapter{Category Layer 18}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{FunctionFieldCategory}{FFCAT}
+\pagepic{ps/v102functionfieldcategory.ps}{FFCAT}{0.70}
+
+{\bf See:}\\
+\pagefrom{MonogenicAlgebra}{MONOGEN}
+
+{\bf Exports:}\\
+\begin{tabular}{lllll}
+\cross{FFCAT}{0} &
+\cross{FFCAT}{1} \\
+\cross{FFCAT}{absolutelyIrreducible?} &
+\cross{FFCAT}{algSplitSimple} \\
+\cross{FFCAT}{associates?} &
+\cross{FFCAT}{basis} \\
+\cross{FFCAT}{branchPoint?} &
+\cross{FFCAT}{branchPointAtInfinity?} \\
+\cross{FFCAT}{characteristic} &
+\cross{FFCAT}{characteristicPolynomial} \\
+\cross{FFCAT}{charthRoot} &
+\cross{FFCAT}{coerce} \\
+\cross{FFCAT}{complementaryBasis} &
+\cross{FFCAT}{conditionP} \\
+\cross{FFCAT}{convert} &
+\cross{FFCAT}{coordinates} \\
+\cross{FFCAT}{createPrimitiveElement} &
+\cross{FFCAT}{D} \\
+\cross{FFCAT}{definingPolynomial} &
+\cross{FFCAT}{derivationCoordinates} \\
+\cross{FFCAT}{differentiate} &
+\cross{FFCAT}{discreteLog} \\
+\cross{FFCAT}{discriminant} &
+\cross{FFCAT}{divide} \\
+\cross{FFCAT}{elliptic} &
+\cross{FFCAT}{elt} \\
+\cross{FFCAT}{euclideanSize} &
+\cross{FFCAT}{expressIdealMember} \\
+\cross{FFCAT}{exquo} &
+\cross{FFCAT}{extendedEuclidean} \\
+\cross{FFCAT}{factor} &
+\cross{FFCAT}{factorsOfCyclicGroupSize} \\
+\cross{FFCAT}{gcd} &
+\cross{FFCAT}{gcdPolynomial} \\
+\cross{FFCAT}{generator} &
+\cross{FFCAT}{genus} \\
+\cross{FFCAT}{hash} &
+\cross{FFCAT}{hyperelliptic} \\
+\cross{FFCAT}{index} &
+\cross{FFCAT}{init} \\
+\cross{FFCAT}{integral?} &
+\cross{FFCAT}{integralAtInfinity?} \\
+\cross{FFCAT}{integralBasis} &
+\cross{FFCAT}{integralBasisAtInfinity} \\
+\cross{FFCAT}{integralCoordinates} &
+\cross{FFCAT}{integralDerivationMatrix} \\
+\cross{FFCAT}{integralMatrix} &
+\cross{FFCAT}{integralMatrixAtInfinity} \\
+\cross{FFCAT}{integralRepresents} &
+\cross{FFCAT}{inv} \\
+\cross{FFCAT}{inverseIntegralMatrix} &
+\cross{FFCAT}{inverseIntegralMatrixAtInfinity} \\
+\cross{FFCAT}{latex} &
+\cross{FFCAT}{lcm} \\
+\cross{FFCAT}{lift} &
+\cross{FFCAT}{lookup} \\
+\cross{FFCAT}{minimalPolynomial} &
+\cross{FFCAT}{multiEuclidean} \\
+\cross{FFCAT}{nextItem} &
+\cross{FFCAT}{nonSingularModel} \\
+\cross{FFCAT}{norm} &
+\cross{FFCAT}{normalizeAtInfinity} \\
+\cross{FFCAT}{numberOfComponents} &
+\cross{FFCAT}{one?} \\
+\cross{FFCAT}{order} &
+\cross{FFCAT}{prime?} \\
+\cross{FFCAT}{primeFrobenius} &
+\cross{FFCAT}{primitive?} \\
+\cross{FFCAT}{primitiveElement} &
+\cross{FFCAT}{primitivePart} \\
+\cross{FFCAT}{principalIdeal} &
+\cross{FFCAT}{ramified?} \\
+\cross{FFCAT}{ramifiedAtInfinity?} &
+\cross{FFCAT}{rank} \\
+\cross{FFCAT}{random} &
+\cross{FFCAT}{rationalPoints} \\
+\cross{FFCAT}{rationalPoint?} &
+\cross{FFCAT}{recip} \\
+\cross{FFCAT}{reduce} &
+\cross{FFCAT}{reduceBasisAtInfinity} \\
+\cross{FFCAT}{reducedSystem} &
+\cross{FFCAT}{regularRepresentation} \\
+\cross{FFCAT}{representationType} &
+\cross{FFCAT}{represents} \\
+\cross{FFCAT}{retract} &
+\cross{FFCAT}{retractIfCan} \\
+\cross{FFCAT}{sample} &
+\cross{FFCAT}{singular?} \\
+\cross{FFCAT}{singularAtInfinity?} &
+\cross{FFCAT}{size} \\
+\cross{FFCAT}{sizeLess?} &
+\cross{FFCAT}{squareFree} \\
+\cross{FFCAT}{squareFreePart} &
+\cross{FFCAT}{subtractIfCan} \\
+\cross{FFCAT}{tableForDiscreteLogarithm} &
+\cross{FFCAT}{trace} \\
+\cross{FFCAT}{traceMatrix} &
+\cross{FFCAT}{unit?} \\
+\cross{FFCAT}{unitCanonical} &
+\cross{FFCAT}{unitNormal} \\
+\cross{FFCAT}{yCoordinates} &
+\cross{FFCAT}{zero?} \\
+\cross{FFCAT}{?*?} &
+\cross{FFCAT}{?**?} \\
+\cross{FFCAT}{?+?} &
+\cross{FFCAT}{?-?} \\
+\cross{FFCAT}{-?} &
+\cross{FFCAT}{?=?} \\
+\cross{FFCAT}{?\^{}?} &
+\cross{FFCAT}{?\~{}=?} \\
+\cross{FFCAT}{?/?} &
+\cross{FFCAT}{?quo?} \\
+\cross{FFCAT}{?rem?} &
+\end{tabular}
+
+TPDHERE:
+\begin{verbatim}
+ 0 : () -> %
+ 1 : () -> %                          
+ associates? : (%,%) -> Boolean
+     if Fraction UP has FIELD
+ basis : () -> Vector %
+ characteristic : () -> NonNegativeInteger
+ characteristicPolynomial : % -> UPUP
+ charthRoot : % -> Union(%,"failed")
+     if Fraction UP has CHARNZ
+ charthRoot : % -> %
+     if Fraction UP has FFIELDC
+ coerce : % -> %
+     if Fraction UP has FIELD
+ coerce : Fraction Integer -> %
+     if Fraction UP has FIELD 
+     or Fraction UP has RETRACT FRAC INT
+ coerce : Fraction UP -> %            
+ coerce : Integer -> %
+ coerce : % -> OutputForm             
+ conditionP : Matrix % -> Union(Vector %,"failed")
+     if Fraction UP has FFIELDC
+ convert : UPUP -> %
+ convert : % -> UPUP                  
+ convert : Vector Fraction UP -> %
+ convert : % -> Vector Fraction UP    
+ coordinates : Vector % -> Matrix Fraction UP
+ coordinates : % -> Vector Fraction UP
+ coordinates : (Vector %,Vector %) -> Matrix Fraction UP
+ coordinates : (%,Vector %) -> Vector Fraction UP
+ createPrimitiveElement : () -> %
+     if Fraction UP has FFIELDC
+ D : % -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,DifferentialRing)) 
+      or 
+        and(
+          has(Fraction UP,DifferentialRing),
+          has(Fraction UP,Field)) 
+      or Fraction UP has FFIELDC
+ D : (%,NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,DifferentialRing)) 
+      or 
+        and(
+          has(Fraction UP,DifferentialRing),
+          has(Fraction UP,Field)) 
+      or Fraction UP has FFIELDC
+ D : (%,Symbol) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol)) 
+      or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ D : (%,List Symbol) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol)) 
+      or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ D : (%,Symbol,NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol)) 
+      or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ D : (%,List Symbol,List NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol)) 
+      or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ D : (%,(Fraction UP -> Fraction UP)) -> %
+     if Fraction UP has FIELD
+ D : (%,(Fraction UP -> Fraction UP),NonNegativeInteger) -> %
+     if Fraction UP has FIELD
+ definingPolynomial : () -> UPUP
+ derivationCoordinates : (Vector %,(Fraction UP -> Fraction UP))
+   -> Matrix Fraction UP
+     if Fraction UP has FIELD
+ differentiate : % -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,DifferentialRing)) 
+      or 
+        and(
+          has(Fraction UP,DifferentialRing),
+          has(Fraction UP,Field)) 
+      or Fraction UP has FFIELDC
+ differentiate : (%,NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,DifferentialRing)) 
+      or 
+        and(
+          has(Fraction UP,DifferentialRing),
+          has(Fraction UP,Field))
+      or Fraction UP has FFIELDC
+ differentiate : (%,Symbol) -> %
+     if 
+       and(
+         has(Fraction UP,Field),
+         has(Fraction UP,PartialDifferentialRing Symbol)) 
+     or 
+      and(
+        has(Fraction UP,PartialDifferentialRing Symbol),
+        has(Fraction UP,Field))
+ differentiate : (%,List Symbol) -> %
+     if 
+       and(
+         has(Fraction UP,Field),
+         has(Fraction UP,PartialDifferentialRing Symbol)) 
+      or 
+       and(
+         has(Fraction UP,PartialDifferentialRing Symbol),
+         has(Fraction UP,Field))
+ differentiate : (%,Symbol,NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol))
+      or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ differentiate : (%,List Symbol,List NonNegativeInteger) -> %
+     if 
+        and(
+          has(Fraction UP,Field),
+          has(Fraction UP,PartialDifferentialRing Symbol))
+       or 
+        and(
+          has(Fraction UP,PartialDifferentialRing Symbol),
+          has(Fraction UP,Field))
+ differentiate : (%,(Fraction UP -> Fraction UP)) -> %
+     if Fraction UP has FIELD
+ differentiate :
+   (%,(Fraction UP -> Fraction UP),NonNegativeInteger) -> %
+     if Fraction UP has FIELD
+ discreteLog : (%,%) -> Union(NonNegativeInteger,"failed")
+     if Fraction UP has FFIELDC
+ discreteLog : % -> NonNegativeInteger
+     if Fraction UP has FFIELDC
+ discriminant : Vector % -> Fraction UP
+ discriminant : () -> Fraction UP     
+ divide : (%,%) -> Record(quotient: %,remainder: %)
+     if Fraction UP has FIELD
+ euclideanSize : % -> NonNegativeInteger
+     if Fraction UP has FIELD
+ expressIdealMember : (List %,%) -> Union(List %,"failed")
+     if Fraction UP has FIELD
+ exquo : (%,%) -> Union(%,"failed")
+     if Fraction UP has FIELD
+ extendedEuclidean : (%,%) ->
+    Record(coef1: %,coef2: %,generator: %)
+     if Fraction UP has FIELD
+ extendedEuclidean : (%,%,%) ->
+    Union(Record(coef1: %,coef2: %),"failed")
+     if Fraction UP has FIELD
+ factor : % -> Factored %
+     if Fraction UP has FIELD
+ factorsOfCyclicGroupSize : () ->
+    List Record(factor: Integer,exponent: Integer)
+     if Fraction UP has FFIELDC
+ gcd : (%,%) -> %
+     if Fraction UP has FIELD
+ gcd : List % -> %
+     if Fraction UP has FIELD
+ gcdPolynomial : (SparseUnivariatePolynomial %,
+                  SparseUnivariatePolynomial %) ->
+                     SparseUnivariatePolynomial %
+     if Fraction UP has FIELD
+ generator : () -> %                  
+ hash : % -> SingleInteger            
+ index : PositiveInteger -> %
+     if Fraction UP has FINITE
+ init : () -> %
+     if Fraction UP has FFIELDC
+ integralCoordinates : % ->
+    Record(num: Vector UP,den: UP)
+ integralDerivationMatrix : (UP -> UP) ->
+    Record(num: Matrix UP,den: UP)
+ integralMatrix : () -> Matrix Fraction UP
+ integralMatrixAtInfinity : () -> Matrix Fraction UP
+ integralRepresents : (Vector UP,UP) -> %
+ inv : % -> %
+     if Fraction UP has FIELD
+ inverseIntegralMatrix : () -> Matrix Fraction UP
+ inverseIntegralMatrixAtInfinity : () ->
+    Matrix Fraction UP
+ latex : % -> String
+ lcm : (%,%) -> %
+     if Fraction UP has FIELD
+ lcm : List % -> %
+     if Fraction UP has FIELD
+ lift : % -> UPUP                     
+ lookup : % -> PositiveInteger
+     if Fraction UP has FINITE
+ minimalPolynomial : % -> UPUP
+     if Fraction UP has FIELD
+ multiEuclidean : (List %,%) -> Union(List %,"failed")
+     if Fraction UP has FIELD
+ nextItem : % -> Union(%,"failed")
+     if Fraction UP has FFIELDC
+ nonSingularModel : Symbol -> List Polynomial F
+     if F has FIELD
+ norm : % -> Fraction UP
+ one? : % -> Boolean                  
+ order : % -> OnePointCompletion PositiveInteger
+     if Fraction UP has FFIELDC
+ order : % -> PositiveInteger
+     if Fraction UP has FFIELDC
+ prime? : % -> Boolean
+     if Fraction UP has FIELD
+ primeFrobenius : % -> %
+     if Fraction UP has FFIELDC
+ primeFrobenius : (%,NonNegativeInteger) -> %
+     if Fraction UP has FFIELDC
+ primitive? : % -> Boolean
+     if Fraction UP has FFIELDC
+ primitiveElement : () -> %
+     if Fraction UP has FFIELDC
+ principalIdeal : List % ->
+   Record(coef: List %,generator: %)
+     if Fraction UP has FIELD
+ rank : () -> PositiveInteger         
+ random : () -> %
+     if Fraction UP has FINITE
+ recip : % -> Union(%,"failed")       
+ reduce : UPUP -> %
+ reduce : Fraction UPUP -> Union(%,"failed")
+     if Fraction UP has FIELD
+ reducedSystem : Matrix % -> Matrix Fraction UP
+ reducedSystem : (Matrix %,Vector %) ->
+   Record(mat: Matrix Fraction UP,vec: Vector Fraction UP)
+ reducedSystem : (Matrix %,Vector %) ->
+   Record(mat: Matrix Integer,vec: Vector Integer)
+     if Fraction UP has LINEXP INT
+ reducedSystem : Matrix % -> Matrix Integer
+     if Fraction UP has LINEXP INT
+ regularRepresentation : % -> Matrix Fraction UP
+ regularRepresentation : (%,Vector %) -> Matrix Fraction UP
+ representationType : () ->
+   Union("prime",polynomial,normal,cyclic)
+     if Fraction UP has FFIELDC
+ represents : Vector Fraction UP -> %
+ represents : (Vector Fraction UP,Vector %) -> %
+ retract : % -> Fraction Integer
+     if Fraction UP has RETRACT FRAC INT
+ retract : % -> Integer
+     if Fraction UP has RETRACT INT
+ retract : % -> Fraction UP
+ retractIfCan : % -> Union(Fraction UP,"failed")
+ retractIfCan : % -> Union(Fraction Integer,"failed")
+     if Fraction UP has RETRACT FRAC INT
+ retractIfCan : % -> Union(Integer,"failed")
+     if Fraction UP has RETRACT INT
+ sample : () -> %                     
+ size : () -> NonNegativeInteger
+     if Fraction UP has FINITE
+ sizeLess? : (%,%) -> Boolean
+     if Fraction UP has FIELD
+ squareFree : % -> Factored %
+     if Fraction UP has FIELD
+ squareFreePart : % -> %
+     if Fraction UP has FIELD
+ subtractIfCan : (%,%) -> Union(%,"failed")
+ tableForDiscreteLogarithm : Integer -> 
+   Table(PositiveInteger,NonNegativeInteger)
+     if Fraction UP has FFIELDC
+ trace : % -> Fraction UP
+ traceMatrix : () -> Matrix Fraction UP
+ traceMatrix : Vector % -> Matrix Fraction UP
+ unit? : % -> Boolean
+     if Fraction UP has FIELD
+ unitCanonical : % -> %
+     if Fraction UP has FIELD
+ unitNormal : % -> Record(unit: %,canonical: %,associate: %)
+     if Fraction UP has FIELD
+ zero? : % -> Boolean                 
+ ?*? : (Fraction UP,%) -> %           
+ ?*? : (%,Fraction UP) -> %
+ ?*? : (%,%) -> %                     
+ ?*? : (Integer,%) -> %
+ ?*? : (PositiveInteger,%) -> %       
+ ?**? : (%,PositiveInteger) -> %
+ ?+? : (%,%) -> %                     
+ ?-? : (%,%) -> %
+ -? : % -> %                          
+ ?=? : (%,%) -> Boolean
+ ?^? : (%,PositiveInteger) -> %       
+ ?~=? : (%,%) -> Boolean
+ ?*? : (%,Fraction Integer) -> % if Fraction UP has FIELD
+ ?*? : (Fraction Integer,%) -> % if Fraction UP has FIELD
+ ?*? : (NonNegativeInteger,%) -> %
+ ?**? : (%,Integer) -> % if Fraction UP has FIELD
+ ?**? : (%,NonNegativeInteger) -> %
+ ?/? : (%,%) -> % if Fraction UP has FIELD
+ ?^? : (%,Integer) -> % if Fraction UP has FIELD
+ ?^? : (%,NonNegativeInteger) -> %
+ ?quo? : (%,%) -> % if Fraction UP has FIELD
+ ?rem? : (%,%) -> % if Fraction UP has FIELD
+\end{verbatim}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ branchPointAtInfinity? : () -> Boolean
+ branchPoint? : UP -> Boolean         
+ branchPoint? : F -> Boolean
+ integralBasis : () -> Vector %       
+ integralBasisAtInfinity : () -> Vector %
+ ramifiedAtInfinity? : () -> Boolean
+ ramified? : UP -> Boolean            
+ ramified? : F -> Boolean
+ singularAtInfinity? : () -> Boolean
+ singular? : F -> Boolean             
+ singular? : UP -> Boolean
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ absolutelyIrreducible? : () -> Boolean
+ algSplitSimple : (%,(UP -> UP)) ->
+      Record(num: %,den: UP,derivden: UP,gd: UP)
+ complementaryBasis : Vector % -> Vector %
+ differentiate : (%,(UP -> UP)) -> %
+ elliptic : () -> Union(UP,"failed")
+ elt : (%,F,F) -> F
+ genus : () -> NonNegativeInteger
+ hyperelliptic : () -> Union(UP,"failed")
+ integral? : % -> Boolean
+ integral? : (%,F) -> Boolean         
+ integral? : (%,UP) -> Boolean
+ integralAtInfinity? : % -> Boolean
+ normalizeAtInfinity : Vector % -> Vector %
+ numberOfComponents : () -> NonNegativeInteger
+ primitivePart : % -> %
+ rationalPoint? : (F,F) -> Boolean
+ rationalPoints : () -> List List F if F has FINITE
+ reduceBasisAtInfinity : Vector % -> Vector %
+ represents : (Vector UP,UP) -> %     
+ yCoordinates : % -> Record(num: Vector UP,den: UP)
+\end{verbatim}
+
+These exports come from Aggregate:
+\begin{verbatim}
+\end{verbatim}
+
+These exports come from Evalable(a:Type):
+\begin{verbatim}
+\end{verbatim}
+
+These exports come from SetCategory:
+\begin{verbatim}
+\end{verbatim}
+
+<<category FFCAT FunctionFieldCategory>>=
+)abbrev category FFCAT FunctionFieldCategory
+++ Function field of a curve
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 19 Mai 1993
+++ Description: This category is a model for the function field of a
+++ plane algebraic curve.
+++ Keywords: algebraic, curve, function, field.
+FunctionFieldCategory(F, UP, UPUP): Category == Definition where
+  F   : UniqueFactorizationDomain
+  UP  : UnivariatePolynomialCategory F
+  UPUP: UnivariatePolynomialCategory Fraction UP
+
+  Z   ==> Integer
+  Q   ==> Fraction F
+  P   ==> Polynomial F
+  RF  ==> Fraction UP
+  QF  ==> Fraction UPUP
+  SY  ==> Symbol
+  REC ==> Record(num:$, den:UP, derivden:UP, gd:UP)
+
+  Definition ==> MonogenicAlgebra(RF, UPUP) with
+    numberOfComponents     : () -> NonNegativeInteger
+      ++ numberOfComponents() returns the number of absolutely irreducible
+      ++ components.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X numberOfComponents()$R
+    genus                  : () -> NonNegativeInteger
+      ++ genus() returns the genus of one absolutely irreducible component
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X genus()$R
+    absolutelyIrreducible? : () -> Boolean
+      ++ absolutelyIrreducible?() tests if the curve absolutely irreducible?
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
+      ++X absolutelyIrreducible?()$R2
+    rationalPoint?         : (F, F) -> Boolean
+      ++ rationalPoint?(a, b) tests if \spad{(x=a,y=b)} is on the curve.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X rationalPoint?(0,0)$R
+      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
+      ++X rationalPoint?(0,0)$R2
+    branchPointAtInfinity? : () -> Boolean
+      ++ branchPointAtInfinity?() tests if there is a branch point 
+      ++ at infinity.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X branchPointAtInfinity?()$R
+      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
+      ++X branchPointAtInfinity?()$R
+    branchPoint?           : F -> Boolean
+      ++ branchPoint?(a) tests whether \spad{x = a} is a branch point.
+    branchPoint?           : UP -> Boolean
+      ++ branchPoint?(p) tests whether \spad{p(x) = 0} is a branch point.
+    singularAtInfinity?    : () -> Boolean
+      ++ singularAtInfinity?() tests if there is a singularity at infinity.
+    singular?              : F -> Boolean
+      ++ singular?(a) tests whether \spad{x = a} is singular.
+    singular?              : UP -> Boolean
+      ++ singular?(p) tests whether \spad{p(x) = 0} is singular.
+    ramifiedAtInfinity?    : () -> Boolean
+      ++ ramifiedAtInfinity?() tests if infinity is ramified.
+    ramified?              : F -> Boolean
+      ++ ramified?(a) tests whether \spad{x = a} is ramified.
+    ramified?              : UP -> Boolean
+      ++ ramified?(p) tests whether \spad{p(x) = 0} is ramified.
+    integralBasis          : () -> Vector $
+      ++ integralBasis() returns the integral basis for the curve.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X integralBasis()$R
+    integralBasisAtInfinity: () -> Vector $
+      ++ integralBasisAtInfinity() returns the local integral basis 
+      ++ at infinity
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X integralBasisAtInfinity()$R
+    integralAtInfinity?    : $  -> Boolean
+      ++ integralAtInfinity?() tests if f is locally integral at infinity.
+    integral?              : $  -> Boolean
+      ++ integral?() tests if f is integral over \spad{k[x]}.
+    complementaryBasis     : Vector $ -> Vector $
+      ++ complementaryBasis(b1,...,bn) returns the complementary basis
+      ++ \spad{(b1',...,bn')} of \spad{(b1,...,bn)}.
+    normalizeAtInfinity    : Vector $ -> Vector $
+      ++ normalizeAtInfinity(v) makes v normal at infinity.
+    reduceBasisAtInfinity  : Vector $ -> Vector $
+      ++ reduceBasisAtInfinity(b1,...,bn) returns \spad{(x**i * bj)}
+      ++ for all i,j such that \spad{x**i*bj} is locally integral 
+      ++ at infinity.
+    integralMatrix         : () -> Matrix RF
+      ++ integralMatrix() returns M such that
+      ++ \spad{(w1,...,wn) = M (1, y, ..., y**(n-1))},
+      ++ where \spad{(w1,...,wn)} is the integral basis of
+      ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X integralMatrix()$R
+    inverseIntegralMatrix  : () -> Matrix RF
+      ++ inverseIntegralMatrix() returns M such that
+      ++ \spad{M (w1,...,wn) = (1, y, ..., y**(n-1))}
+      ++ where \spad{(w1,...,wn)} is the integral basis of
+      ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X inverseIntegralMatrix()$R
+    integralMatrixAtInfinity       : () -> Matrix RF
+      ++ integralMatrixAtInfinity() returns M such that
+      ++ \spad{(v1,...,vn) = M (1, y, ..., y**(n-1))}
+      ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
+      ++ returned by \spad{infIntBasis()}.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X integralMatrixAtInfinity()$R
+    inverseIntegralMatrixAtInfinity: () -> Matrix RF
+      ++ inverseIntegralMatrixAtInfinity() returns M such
+      ++ that \spad{M (v1,...,vn) = (1, y, ..., y**(n-1))}
+      ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
+      ++ returned by \spad{infIntBasis()}.
+      ++
+      ++X P0 := UnivariatePolynomial(x, Integer)
+      ++X P1 := UnivariatePolynomial(y, Fraction P0)
+      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
+      ++X inverseIntegralMatrixAtInfinity()$R
+    yCoordinates           : $ -> Record(num:Vector(UP), den:UP)
+      ++ yCoordinates(f) returns \spad{[[A1,...,An], D]} such that
+      ++ \spad{f = (A1 + A2 y +...+ An y**(n-1)) / D}.
+    represents             : (Vector UP, UP) -> $
+      ++ represents([A0,...,A(n-1)],D) returns
+      ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
+    integralCoordinates    : $ -> Record(num:Vector(UP), den:UP)
+      ++ integralCoordinates(f) returns \spad{[[A1,...,An], D]} such that
+      ++ \spad{f = (A1 w1 +...+ An wn) / D}  where \spad{(w1,...,wn)} is the
+      ++ integral basis returned by \spad{integralBasis()}.
+    integralRepresents     : (Vector UP, UP) -> $
+      ++ integralRepresents([A1,...,An], D) returns
+      ++ \spad{(A1 w1+...+An wn)/D}
+      ++ where \spad{(w1,...,wn)} is the integral
+      ++ basis of \spad{integralBasis()}.
+    integralDerivationMatrix:(UP -> UP) -> Record(num:Matrix(UP),den:UP)
+      ++ integralDerivationMatrix(d) extends the derivation d from UP to $
+      ++ and returns (M, Q) such that the i^th row of M divided by Q form
+      ++ the coordinates of \spad{d(wi)} with respect to \spad{(w1,...,wn)}
+      ++ where \spad{(w1,...,wn)} is the integral basis returned
+      ++ by integralBasis().
+    integral?              : ($,  F) -> Boolean
+      ++ integral?(f, a) tests whether f is locally integral at \spad{x = a}.
+    integral?              : ($, UP) -> Boolean
+      ++ integral?(f, p) tests whether f is locally integral at 
+      ++ \spad{p(x) = 0}
+    differentiate          : ($, UP -> UP) -> $
+      ++ differentiate(x, d) extends the derivation d from UP to $ and
+      ++ applies it to x.
+    represents             : (Vector UP, UP) -> $
+      ++ represents([A0,...,A(n-1)],D) returns
+      ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
+    primitivePart          : $ -> $
+      ++ primitivePart(f) removes the content of the denominator and
+      ++ the common content of the numerator of f.
+    elt                    : ($, F, F) -> F
+      ++ elt(f,a,b) or f(a, b) returns the value of f 
+      ++ at the point \spad{(x = a, y = b)}
+      ++ if it is not singular.
+    elliptic               : () -> Union(UP, "failed")
+      ++ elliptic() returns \spad{p(x)} if the curve is the elliptic
+      ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
+    hyperelliptic          : () -> Union(UP, "failed")
+      ++ hyperelliptic() returns \spad{p(x)} if the curve is the 
+      ++ hyperelliptic
+      ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
+    algSplitSimple         : ($, UP -> UP) -> REC
+      ++ algSplitSimple(f, D) returns \spad{[h,d,d',g]} such that 
+      ++ \spad{f=h/d},
+      ++ \spad{h} is integral at all the normal places w.r.t. \spad{D},
+      ++ \spad{d' = Dd}, \spad{g = gcd(d, discriminant())} and \spad{D}
+      ++ is the derivation to use. \spad{f} must have at most simple finite
+      ++ poles.
+    if F has Field then
+      nonSingularModel: SY -> List Polynomial F
+        ++ nonSingularModel(u) returns the equations in u1,...,un of
+        ++ an affine non-singular model for the curve.
+    if F has Finite then
+      rationalPoints: () -> List List F
+        ++ rationalPoints() returns the list of all the affine 
+        ++rational points.
+   add
+    import InnerCommonDenominator(UP, RF, Vector UP, Vector RF)
+    import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+
+    repOrder: (Matrix RF, Z) -> Z
+    Q2RF    : Q  -> RF
+    infOrder: RF -> Z
+    infValue: RF -> Fraction F
+    intvalue: (Vector UP, F, F) -> F
+    rfmonom : Z  -> RF
+    kmin    : (Matrix RF,Vector Q) -> Union(Record(pos:Z,km:Z),"failed")
+
+    Q2RF q                 == numer(q)::UP / denom(q)::UP
+    infOrder f             == (degree denom f)::Z - (degree numer f)::Z
+    integral? f            == ground?(integralCoordinates(f).den)
+    integral?(f:$, a:F)    == (integralCoordinates(f).den)(a) ^= 0
+--    absolutelyIrreducible? == one? numberOfComponents()
+    absolutelyIrreducible? == numberOfComponents() = 1
+    yCoordinates f         == splitDenominator coordinates f
+
+    hyperelliptic() ==
+      degree(f := definingPolynomial()) ^= 2 => "failed"
+      (u:=retractIfCan(reductum f)@Union(RF,"failed"))
+        case "failed" => "failed"
+      (v:=retractIfCan(-(u::RF) / leadingCoefficient f)@Union(UP, "failed"))
+        case "failed" => "failed"
+      odd? degree(p := v::UP) => p
+      "failed"
+
+    algSplitSimple(f, derivation) ==
+      cd := splitDenominator lift f
+      dd := (cd.den exquo (g := gcd(cd.den, derivation(cd.den))))::UP
+      [reduce(inv(g::RF) * cd.num), dd, derivation dd,
+                                    gcd(dd, retract(discriminant())@UP)]
+
+    elliptic() ==
+      (u := hyperelliptic()) case "failed" => "failed"
+      degree(p := u::UP) = 3 => p
+      "failed"
+
+    rationalPoint?(x, y)   ==
+      zero?((definingPolynomial() (y::UP::RF)) (x::UP::RF))
+
+    if F has Field then
+      import PolyGroebner(F)
+      import MatrixCommonDenominator(UP, RF)
+
+      UP2P  : (UP,   P)    -> P
+      UPUP2P: (UPUP, P, P) -> P
+
+      UP2P(p, x) ==
+        (map(#1::P, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
+                                     P, SparseUnivariatePolynomial P)) x
+
+      UPUP2P(p, x, y) ==
+        (map(UP2P(retract(#1)@UP, x),
+             p)$UnivariatePolynomialCategoryFunctions2(RF, UPUP,
+                                     P, SparseUnivariatePolynomial P)) y
+
+      nonSingularModel u ==
+        d    := commonDenominator(coordinates(w := integralBasis()))::RF
+        vars := [concat(string u, string i)::SY for i in 1..(n := #w)]
+        x    := "%%dummy1"::SY
+        y    := "%%dummy2"::SY
+        select_!(zero?(degree(#1, x)) and zero?(degree(#1, y)),
+                 lexGroebner([v::P - UPUP2P(lift(d * w.i), x::P, y::P)
+                    for v in vars for i in 1..n], concat([x, y], vars)))
+
+    if F has Finite then
+      ispoint: (UPUP, F, F) -> List F
+
+-- must use the 'elt function explicitely or the compiler takes 45 mins
+-- on that function    MB 5/90
+-- still takes ages : I split the expression up. JHD 6/Aug/90
+      ispoint(p, x, y) ==
+        jhd:RF:=p(y::UP::RF)
+        zero?(jhd (x::UP::RF)) => [x, y]
+        empty()
+
+      rationalPoints() ==
+        p := definingPolynomial()
+        concat [[pt for y in 1..size()$F | not empty?(pt :=
+          ispoint(p, index(x::PositiveInteger)$F,
+                     index(y::PositiveInteger)$F))]$List(List F)
+                                for x in 1..size()$F]$List(List(List F))
+
+    intvalue(v, x, y) ==
+      singular? x => error "Point is singular"
+      mini := minIndex(w := integralBasis())
+      rec := yCoordinates(+/[qelt(v, i)::RF * qelt(w, i)
+                           for i in mini .. maxIndex w])
+      n   := +/[(qelt(rec.num, i) x) *
+                (y ** ((i - mini)::NonNegativeInteger))
+                           for i in mini .. maxIndex w]
+      zero?(d := (rec.den) x) =>
+        zero? n => error "0/0 -- cannot compute value yet"
+        error "Shouldn't happen"
+      (n exquo d)::F
+
+    elt(f, x, y) ==
+      rec := integralCoordinates f
+      n   := intvalue(rec.num, x, y)
+      zero?(d := (rec.den) x) =>
+        zero? n => error "0/0 -- cannot compute value yet"
+        error "Function has a pole at the given point"
+      (n exquo d)::F
+
+    primitivePart f ==
+      cd := yCoordinates f
+      d  := gcd([content qelt(cd.num, i)
+                 for i in minIndex(cd.num) .. maxIndex(cd.num)]$List(F))
+                   * primitivePart(cd.den)
+      represents [qelt(cd.num, i) / d
+               for i in minIndex(cd.num) .. maxIndex(cd.num)]$Vector(RF)
+
+    reduceBasisAtInfinity b ==
+      x := monomial(1, 1)$UP ::RF
+      concat([[f for j in 0.. while
+                integralAtInfinity?(f := x**j * qelt(b, i))]$Vector($)
+                      for i in minIndex b .. maxIndex b]$List(Vector $))
+
+    complementaryBasis b ==
+      m := inverse(traceMatrix b)::Matrix(RF)
+      [represents row(m, i) for i in minRowIndex m .. maxRowIndex m]
+
+    integralAtInfinity? f ==
+      not any?(infOrder(#1) < 0,
+         coordinates(f) * inverseIntegralMatrixAtInfinity())$Vector(RF)
+
+    numberOfComponents() ==
+      count(integralAtInfinity?, integralBasis())$Vector($)
+
+    represents(v:Vector UP, d:UP) ==
+      represents
+        [qelt(v, i) / d for i in minIndex v .. maxIndex v]$Vector(RF)
+
+    genus() ==
+      ds := discriminant()
+      d  := degree(retract(ds)@UP) + infOrder(ds * determinant(
+             integralMatrixAtInfinity() * inverseIntegralMatrix()) ** 2)
+      dd := (((d exquo 2)::Z - rank()) exquo numberOfComponents())::Z
+      (dd + 1)::NonNegativeInteger
+
+    repOrder(m, i) ==
+      nostart:Boolean := true
+      ans:Z := 0
+      r := row(m, i)
+      for j in minIndex r .. maxIndex r | qelt(r, j) ^= 0 repeat
+        ans :=
+          nostart => (nostart := false; infOrder qelt(r, j))
+          min(ans, infOrder qelt(r,j))
+      nostart => error "Null row"
+      ans
+
+    infValue f ==
+      zero? f => 0
+      (n := infOrder f) > 0 => 0
+      zero? n =>
+        (leadingCoefficient numer f) / (leadingCoefficient denom f)
+      error "f not locally integral at infinity"
+
+    rfmonom n ==
+      n < 0 => inv(monomial(1, (-n)::NonNegativeInteger)$UP :: RF)
+      monomial(1, n::NonNegativeInteger)$UP :: RF
+
+    kmin(m, v) ==
+      nostart:Boolean := true
+      k:Z := 0
+      ii  := minRowIndex m - (i0  := minIndex v)
+      for i in minIndex v .. maxIndex v | qelt(v, i) ^= 0 repeat
+        nk := repOrder(m, i + ii)
+        if nostart then (nostart := false; k := nk; i0 := i)
+        else
+          if nk < k then (k := nk; i0 := i)
+      nostart => "failed"
+      [i0, k]
+
+    normalizeAtInfinity w ==
+      ans   := copy w
+      infm  := inverseIntegralMatrixAtInfinity()
+      mhat  := zero(rank(), rank())$Matrix(RF)
+      ii    := minIndex w - minRowIndex mhat
+      repeat
+        m := coordinates(ans) * infm
+        r := [rfmonom repOrder(m, i)
+                     for i in minRowIndex m .. maxRowIndex m]$Vector(RF)
+        for i in minRowIndex m .. maxRowIndex m repeat
+          for j in minColIndex m .. maxColIndex m repeat
+            qsetelt_!(mhat, i, j, qelt(r, i + ii) * qelt(m, i, j))
+        sol := first nullSpace transpose map(infValue,
+                mhat)$MatrixCategoryFunctions2(RF, Vector RF, Vector RF,
+                             Matrix RF, Q, Vector Q, Vector Q, Matrix Q)
+        (pr := kmin(m, sol)) case "failed" => return ans
+        qsetelt_!(ans, pr.pos,
+         +/[Q2RF(qelt(sol, i)) * rfmonom(repOrder(m, i - ii) - pr.km)
+                  * qelt(ans, i) for i in minIndex sol .. maxIndex sol])
+
+    integral?(f:$, p:UP) ==
+      (r:=retractIfCan(p)@Union(F,"failed")) case F => integral?(f,r::F)
+      (integralCoordinates(f).den exquo p) case "failed"
+
+    differentiate(f:$, d:UP -> UP) ==
+      differentiate(f, differentiate(#1, d)$RF)
+
+@
+<<FFCAT.dotabb>>=
+"FFCAT"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FFCAT"];
+"FFCAT" -> "MONOGEN"
+
+@
+<<FFCAT.dotfull>>=
+"FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FFCAT"];
+"FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))"
+   -> "MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))"
+
+@
+<<FFCAT.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))"
+ [color=lightblue,href="bookvol10.2.pdf#nameddest=FFCAT"];
+"FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))"
+   -> "MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))"
+
+"MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))"
+ [color=seagreen,href="bookvol10.2.pdf#nameddest=MONOGEN"];
+"MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))" ->
+    "MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))"
+
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))"
+ [color=lightblue];
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))" ->
+    "FRAMALG..."
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))" ->
+    "COMRING..."
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))" ->
+    "KONVERT..."
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))" ->
+    "FRETRCT..."
+"MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))" ->
+    "FLINEXP..."
+
+"FRAMALG..." [color=lightblue];
+"COMRING..." [color=lightblue];
+"KONVERT..." [color=lightblue];
+"FRETRCT..." [color=lightblue];
+"FLINEXP..." [color=lightblue];
+}
+
+@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{FramedAlgebra}{FRAMALG}
 \pagepic{ps/v102framedalgebra.ps}{FRAMALG}{0.45}
 
@@ -24609,14 +28139,19 @@ Note that this code is not included in the generated catdef.spad file.
 <<category EUCDOM EuclideanDomain>>
 <<category EVALAB Evalable>>
 <<category FIELD Field>>
+<<category FINAALG FiniteRankNonAssociativeAlgebra>>
 <<category FINITE Finite>>
 <<category FINRALG FiniteRankAlgebra>>
+<<category FFCAT FunctionFieldCategory>>
 <<category FLAGG FiniteLinearAggregate>>
 <<category FLINEXP FullyLinearlyExplicitRingOver>>
 <<category FRAMALG FramedAlgebra>>
 <<category FRETRCT FullyRetractableTo>>
+<<category FRNAALG FramedNonAssociativeAlgebra>>
 <<category FSAGG FiniteSetAggregate>>
 <<category GCDDOM GcdDomain>>
+<<category GRALG GradedAlgebra>>
+<<category GRMOD GradedModule>>
 <<category GROUP Group>>
 <<category HOAGG HomogeneousAggregate>>
 <<category IEVALAB InnerEvalable>>
@@ -24631,10 +28166,15 @@ Note that this code is not included in the generated catdef.spad file.
 <<category LOGIC Logic>>
 <<category LSAGG ListAggregate>>
 <<category MODULE Module>>
+<<category MONAD Monad>>
+<<category MONADWU MonadWithUnit>>
 <<category MONOID Monoid>>
 <<category MONOGEN MonogenicAlgebra>>
 <<category MDAGG MultiDictionary>>
 <<category MSETAGG MultisetAggregate>>
+<<category NAALG NonAssociativeAlgebra>>
+<<category NARNG NonAssociativeRng>>
+<<category NASRING NonAssociativeRing>>
 <<category OAGROUP OrderedAbelianGroup>>
 <<category OAMON OrderedAbelianMonoid>>
 <<category OAMONS OrderedAbelianMonoidSup>>
@@ -24708,14 +28248,19 @@ digraph dotabb {
 <<EUCDOM.dotabb>>
 <<EVALAB.dotabb>>
 <<FIELD.dotabb>>
+<<FINAALG.dotabb>>
 <<FINITE.dotabb>>
 <<FINRALG.dotabb>>
+<<FFCAT.dotabb>>
 <<FLAGG.dotabb>>
 <<FLINEXP.dotabb>>
 <<FRAMALG.dotabb>>
 <<FRETRCT.dotabb>>
+<<FRNAALG.dotabb>>
 <<FSAGG.dotabb>>
 <<GCDDOM.dotabb>>
+<<GRALG.dotabb>>
+<<GRMOD.dotabb>>
 <<HOAGG.dotabb>>
 <<IEVALAB.dotabb>>
 <<INTDOM.dotabb>>
@@ -24729,10 +28274,15 @@ digraph dotabb {
 <<LOGIC.dotabb>>
 <<LSAGG.dotabb>>
 <<MODULE.dotabb>>
+<<MONAD.dotabb>>
+<<MONADWU.dotabb>>
 <<MDAGG.dotabb>>
 <<MONOID.dotabb>>
 <<MONOGEN.dotabb>>
 <<MSETAGG.dotabb>>
+<<NAALG.dotabb>>
+<<NARNG.dotabb>>
+<<NASRING.dotabb>>
 <<OAGROUP.dotabb>>
 <<OAMON.dotabb>>
 <<OAMONS.dotabb>>
@@ -24809,14 +28359,19 @@ digraph dotfull {
 <<EUCDOM.dotfull>>
 <<EVALAB.dotfull>>
 <<FIELD.dotfull>>
+<<FINAALG.dotfull>>
 <<FINITE.dotfull>>
 <<FINRALG.dotfull>>
+<<FFCAT.dotfull>>
 <<FLAGG.dotfull>>
 <<FLINEXP.dotfull>>
 <<FRAMALG.dotfull>>
 <<FRETRCT.dotfull>>
+<<FRNAALG.dotfull>>
 <<FSAGG.dotfull>>
 <<GCDDOM.dotfull>>
+<<GRALG.dotfull>>
+<<GRMOD.dotfull>>
 <<HOAGG.dotfull>>
 <<IEVALAB.dotfull>>
 <<INTDOM.dotfull>>
@@ -24830,10 +28385,15 @@ digraph dotfull {
 <<LOGIC.dotfull>>
 <<LSAGG.dotfull>>
 <<MODULE.dotfull>>
+<<MONAD.dotfull>>
+<<MONADWU.dotfull>>
 <<MDAGG.dotfull>>
 <<MONOID.dotfull>>
 <<MONOGEN.dotfull>>
 <<MSETAGG.dotfull>>
+<<NAALG.dotfull>>
+<<NARNG.dotfull>>
+<<NASRING.dotfull>>
 <<OAGROUP.dotfull>>
 <<OAMON.dotfull>>
 <<OAMONS.dotabb>>
@@ -24871,7 +28431,14 @@ digraph dotfull {
 @
 \eject
 \begin{thebibliography}{99}
-\bibitem none
+\bibitem{1} N. Jacobson: Structure and Representations of Jordan Algebras
+AMS, Providence, 1968
+\bibitem{2} MacLane and Birkhoff, Algebra 2d Edition, MacMillan 1979
+\bibitem{3} Encyclopedic Dictionary of Mathematics, MIT Press, 1977
+\bibitem{4} R.D. Schafer: An Introduction to Nonassociative Algebras
+Academic Press, New York, 1966
+\bibitem{5} R. Wisbauer: Bimodule Structure of Algebra
+Lecture Notes Univ. Duesseldorf 1991
 \end{thebibliography}
 \printindex
 \end{document}
diff --git a/books/ps/v102finiteranknonassociativealgebra.ps b/books/ps/v102finiteranknonassociativealgebra.ps
new file mode 100644
index 0000000..a99aeb9
--- /dev/null
+++ b/books/ps/v102finiteranknonassociativealgebra.ps
@@ -0,0 +1,884 @@
+%!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 498 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 498 584
+%%PageOrientation: Portrait
+gsave
+36 36 462 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
+460 546 lineto
+460 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 546 lineto
+460 546 lineto
+460 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% FiniteRankNonAssociativeAlgebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 347 540 moveto
+13 540 lineto
+13 504 lineto
+347 504 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 347 540 moveto
+13 540 lineto
+13 504 lineto
+347 504 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+21 517 moveto
+(FiniteRankNonAssociativeAlgebra\(a:CommutativeRing\))
+[7.44 3.84 6.96 3.84 3.84 6.24 9.36 6.24 6.96 6.96 9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 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
+% NonAssociativeAlgebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 316 468 moveto
+44 468 lineto
+44 432 lineto
+316 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 316 468 moveto
+44 468 lineto
+44 432 lineto
+316 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+51 445 moveto
+(NonAssociativeAlgebra\(a:CommutativeRing\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 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
+% FiniteRankNonAssociativeAlgebra(a:CommutativeRing)->NonAssociativeAlgebra(a:CommutativeRing)
+newpath 180 504 moveto
+180 496 180 487 180 478 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 184 478 moveto
+180 468 lineto
+177 478 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 184 478 moveto
+180 468 lineto
+177 478 lineto
+closepath
+stroke
+end grestore
+% NonAssociativeRng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+20 373 moveto
+(NonAssociativeRng\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeAlgebra(a:CommutativeRing)->NonAssociativeRng()
+newpath 155 432 moveto
+143 423 128 412 114 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 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 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+195 373 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
+% NonAssociativeAlgebra(a:CommutativeRing)->Module(a:CommutativeRing)
+newpath 205 432 moveto
+217 423 232 412 246 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 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 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+114 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
+% NonAssociativeRng()->ABELGRP...
+newpath 65 360 moveto
+57 350 47 337 40 324 curveto
+21 286 11 276 10 234 curveto
+10 234 10 234 10 162 curveto
+11 107 64 65 105 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+stroke
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+57 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()->Monad()
+newpath 82 360 moveto
+82 352 82 343 82 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 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 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+149 301 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 284 360 moveto
+286 352 288 343 290 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 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 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+46 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
+% Monad()->SETCAT...
+newpath 81 288 moveto
+80 280 80 271 79 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 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 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+141 229 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Monad()->REPSQ...
+newpath 104 288 moveto
+115 279 128 268 139 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 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 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+230 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
+% BiModule(a:CommutativeRing,b:CommutativeRing)->BiModule(a:Ring,b:Ring)
+newpath 299 288 moveto
+300 280 300 271 301 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 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 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+95 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 265 216 moveto
+245 206 220 195 199 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 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 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 303 216 moveto
+303 208 303 199 303 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+97 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 152 144 moveto
+152 136 152 127 152 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 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 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 302 144 moveto
+302 136 302 127 302 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->ABELGRP...
+newpath 263 72 moveto
+243 62 219 51 198 40 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->ABELGRP...
+newpath 152 72 moveto
+152 64 152 55 152 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102framednonassociativealgebra.ps b/books/ps/v102framednonassociativealgebra.ps
new file mode 100644
index 0000000..820cec7
--- /dev/null
+++ b/books/ps/v102framednonassociativealgebra.ps
@@ -0,0 +1,930 @@
+%!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 498 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 498 656
+%%PageOrientation: Portrait
+gsave
+36 36 462 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
+460 618 lineto
+460 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 618 lineto
+460 618 lineto
+460 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% FramedNonAssociativeAlgebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 337 612 moveto
+23 612 lineto
+23 576 lineto
+337 576 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 337 612 moveto
+23 612 lineto
+23 576 lineto
+337 576 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+31 589 moveto
+(FramedNonAssociativeAlgebra\(a:CommutativeRing\))
+[7.44 4.8 6.24 10.8 6.24 6.96 9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 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
+% FiniteRankNonAssociativeAlgebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 347 540 moveto
+13 540 lineto
+13 504 lineto
+347 504 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 347 540 moveto
+13 540 lineto
+13 504 lineto
+347 504 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+21 517 moveto
+(FiniteRankNonAssociativeAlgebra\(a:CommutativeRing\))
+[7.44 3.84 6.96 3.84 3.84 6.24 9.36 6.24 6.96 6.96 9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 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
+% FramedNonAssociativeAlgebra(a:CommutativeRing)->FiniteRankNonAssociativeAlgebra(a:CommutativeRing)
+newpath 180 576 moveto
+180 568 180 559 180 550 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 184 550 moveto
+180 540 lineto
+177 550 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 184 550 moveto
+180 540 lineto
+177 550 lineto
+closepath
+stroke
+end grestore
+% NonAssociativeAlgebra(a:CommutativeRing)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 316 468 moveto
+44 468 lineto
+44 432 lineto
+316 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 316 468 moveto
+44 468 lineto
+44 432 lineto
+316 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+51 445 moveto
+(NonAssociativeAlgebra\(a:CommutativeRing\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 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
+% FiniteRankNonAssociativeAlgebra(a:CommutativeRing)->NonAssociativeAlgebra(a:CommutativeRing)
+newpath 180 504 moveto
+180 496 180 487 180 478 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 184 478 moveto
+180 468 lineto
+177 478 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 184 478 moveto
+180 468 lineto
+177 478 lineto
+closepath
+stroke
+end grestore
+% NonAssociativeRng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+20 373 moveto
+(NonAssociativeRng\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeAlgebra(a:CommutativeRing)->NonAssociativeRng()
+newpath 155 432 moveto
+143 423 128 412 114 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 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 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+195 373 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
+% NonAssociativeAlgebra(a:CommutativeRing)->Module(a:CommutativeRing)
+newpath 205 432 moveto
+217 423 232 412 246 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 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 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+114 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
+% NonAssociativeRng()->ABELGRP...
+newpath 65 360 moveto
+57 350 47 337 40 324 curveto
+21 286 11 276 10 234 curveto
+10 234 10 234 10 162 curveto
+11 107 64 65 105 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+stroke
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+57 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()->Monad()
+newpath 82 360 moveto
+82 352 82 343 82 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 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 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+149 301 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 284 360 moveto
+286 352 288 343 290 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 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 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+46 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
+% Monad()->SETCAT...
+newpath 81 288 moveto
+80 280 80 271 79 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 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 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+141 229 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Monad()->REPSQ...
+newpath 104 288 moveto
+115 279 128 268 139 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 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 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+230 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
+% BiModule(a:CommutativeRing,b:CommutativeRing)->BiModule(a:Ring,b:Ring)
+newpath 299 288 moveto
+300 280 300 271 301 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 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 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+95 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 265 216 moveto
+245 206 220 195 199 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 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 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 303 216 moveto
+303 208 303 199 303 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+97 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 152 144 moveto
+152 136 152 127 152 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 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 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 302 144 moveto
+302 136 302 127 302 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->ABELGRP...
+newpath 263 72 moveto
+243 62 219 51 198 40 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->ABELGRP...
+newpath 152 72 moveto
+152 64 152 55 152 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102functionfieldcategory.ps b/books/ps/v102functionfieldcategory.ps
new file mode 100644
index 0000000..3bf5fce
--- /dev/null
+++ b/books/ps/v102functionfieldcategory.ps
@@ -0,0 +1,575 @@
+%!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 564 296
+%%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 564 296
+%%PageOrientation: Portrait
+gsave
+36 36 528 260 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 258 lineto
+526 258 lineto
+526 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 258 lineto
+526 258 lineto
+526 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))
+[ /Rect [ 63 216 477 252 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=FFCAT) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 477 252 moveto
+63 252 lineto
+63 216 lineto
+477 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 477 252 moveto
+63 252 lineto
+63 216 lineto
+477 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+70 229 moveto
+(FunctionFieldCategory\(a:UFD,b:UPOLYC\(a\),c:UPOLYC\(Fraction\(b\)\)\))
+[7.44 6.96 6.96 6.24 3.84 3.84 6.96 6.96 7.44 3.84 6.24 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 10.08 7.68 10.08 3.6 6.96 3.84 10.08 7.68 10.08 7.2 9.12 9.36 4.56 6.24 4.56 3.6 6.24 3.84 10.08 7.68 10.08 7.2 9.12 9.36 4.56 7.44 4.8 6.24 6.24 3.84 3.84 6.96 6.96 4.56 6.96 4.56 4.56 4.56]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))
+[ /Rect [ 24 144 516 180 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=MONOGEN) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 516 180 moveto
+24 180 lineto
+24 144 lineto
+516 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 516 180 moveto
+24 180 lineto
+24 144 lineto
+516 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+31 157 moveto
+(MonogenicAlgebra\(a:FRAC\(UPOLYC\(UFD\)\),b:UPOLYC\(FRAC\(UPOLYC\(UFD\)\)\)\))
+[12.48 6.96 6.96 6.96 6.72 6.24 6.96 3.84 6.24 10.08 3.84 6.72 6.24 6.96 4.8 6.24 4.56 6.24 3.84 7.68 9.36 9.36 9.36 4.56 10.08 7.68 10.08 7.2 9.12 9.36 4.56 10.08 7.68 10.08 4.56 4.56 3.6 6.96 3.84 10.08 7.68 10.08 7.2 9.12 9.36 4.56 7.68 9.36 9.36 9.36 4.56 10.08 7.68 10.08 7.2 9.12 9.36 4.56 10.08 7.68 10.08 4.56 4.56 4.56 4.56]
+xshow
+end grestore
+end grestore
+% FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(Fraction(b)))->MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))
+newpath 270 216 moveto
+270 208 270 199 270 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 274 190 moveto
+270 180 lineto
+267 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 274 190 moveto
+270 180 lineto
+267 190 lineto
+closepath
+stroke
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 495 108 moveto
+45 108 lineto
+45 72 lineto
+495 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 495 108 moveto
+45 108 lineto
+45 72 lineto
+495 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+52 85 moveto
+(MonogenicAlgebra\(a:CommutativeRing,b:UnivariatePolynomialCategory\(a\)\))
+[12.48 6.96 6.96 6.96 6.72 6.24 6.96 3.84 6.24 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 3.6 6.96 3.84 9.6 6.96 3.84 6.72 6.24 5.04 3.84 6.24 3.84 6.24 7.44 6.96 3.6 6.96 6.96 6.96 10.8 3.84 6.24 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))->MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))
+newpath 270 144 moveto
+270 136 270 127 270 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 274 118 moveto
+270 108 lineto
+267 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 274 118 moveto
+270 108 lineto
+267 118 lineto
+closepath
+stroke
+end grestore
+% FRAMALG...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 96 36 moveto
+0 36 lineto
+0 0 lineto
+96 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 96 36 moveto
+0 36 lineto
+0 0 lineto
+96 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 13 moveto
+(FRAMALG...)
+[7.68 9.36 10.08 12.48 10.08 8.64 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))->FRAMALG...
+newpath 214 72 moveto
+181 61 139 48 106 37 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 107 34 moveto
+96 34 lineto
+105 40 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 107 34 moveto
+96 34 lineto
+105 40 lineto
+closepath
+stroke
+end grestore
+% COMRING...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 206 36 moveto
+114 36 lineto
+114 0 lineto
+206 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 206 36 moveto
+114 36 lineto
+114 0 lineto
+206 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+121 13 moveto
+(COMRING...)
+[9.12 10.08 12.48 9.36 4.56 9.84 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))->COMRING...
+newpath 242 72 moveto
+228 63 211 52 196 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 197 39 moveto
+187 36 lineto
+193 44 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 197 39 moveto
+187 36 lineto
+193 44 lineto
+closepath
+stroke
+end grestore
+% KONVERT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 316 36 moveto
+224 36 lineto
+224 0 lineto
+316 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 316 36 moveto
+224 36 lineto
+224 0 lineto
+316 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+231 13 moveto
+(KONVERT...)
+[9.12 10.08 10.08 10.08 8.64 8.88 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))->KONVERT...
+newpath 270 72 moveto
+270 64 270 55 270 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 274 46 moveto
+270 36 lineto
+267 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 274 46 moveto
+270 36 lineto
+267 46 lineto
+closepath
+stroke
+end grestore
+% FRETRCT...
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 420 36 moveto
+334 36 lineto
+334 0 lineto
+420 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 420 36 moveto
+334 36 lineto
+334 0 lineto
+420 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+341 13 moveto
+(FRETRCT...)
+[7.68 9.36 8.64 8.64 8.88 9.36 7.44 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))->FRETRCT...
+newpath 297 72 moveto
+311 63 327 52 341 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 344 44 moveto
+350 36 lineto
+340 39 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 344 44 moveto
+350 36 lineto
+340 39 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 520 36 moveto
+438 36 lineto
+438 0 lineto
+520 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 520 36 moveto
+438 36 lineto
+438 0 lineto
+520 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+445 13 moveto
+(FLINEXP...)
+[7.68 8.64 4.56 10.08 8.64 10.08 6.24 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% MonogenicAlgebra(a:CommutativeRing,b:UnivariatePolynomialCategory(a))->FLINEXP...
+newpath 323 72 moveto
+352 63 388 50 429 36 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 430 39 moveto
+438 33 lineto
+427 33 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 430 39 moveto
+438 33 lineto
+427 33 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102gradedalgebra.ps b/books/ps/v102gradedalgebra.ps
new file mode 100644
index 0000000..e618c2e
--- /dev/null
+++ b/books/ps/v102gradedalgebra.ps
@@ -0,0 +1,654 @@
+%!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 501 440
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+	dup 1 exch div /InvScaleFactor exch def
+	dup scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+%%Page: 1 1
+%%PageBoundingBox: 36 36 501 440
+%%PageOrientation: Portrait
+gsave
+36 36 465 404 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+463 402 lineto
+463 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+463 402 lineto
+463 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 421 396 moveto
+95 396 lineto
+95 360 lineto
+421 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 421 396 moveto
+95 396 lineto
+95 360 lineto
+421 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+102 373 moveto
+(GradedAlgebra\(a:CommutativeRing,b:AbelianMonoid\))
+[10.08 4.8 6.24 6.96 6.24 6.96 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 3.6 6.96 3.84 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56]
+xshow
+end grestore
+end grestore
+% GradedModule(a:CommutativeRing,b:AbelianMonoid)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 326 324 moveto
+0 324 lineto
+0 288 lineto
+326 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 326 324 moveto
+0 324 lineto
+0 288 lineto
+326 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 301 moveto
+(GradedModule\(a:CommutativeRing,b:AbelianMonoid\))
+[10.08 4.8 6.24 6.96 6.24 6.96 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.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56]
+xshow
+end grestore
+end grestore
+% GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)->GradedModule(a:CommutativeRing,b:AbelianMonoid)
+newpath 234 360 moveto
+223 351 208 340 195 330 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 197 327 moveto
+187 324 lineto
+193 333 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 197 327 moveto
+187 324 lineto
+193 333 lineto
+closepath
+stroke
+end grestore
+% RetractableTo(CommutativeRing)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 457 252 moveto
+251 252 lineto
+251 216 lineto
+457 216 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 457 252 moveto
+251 252 lineto
+251 216 lineto
+457 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+259 229 moveto
+(RetractableTo\(CommutativeRing\))
+[9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 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
+% GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)->RetractableTo(CommutativeRing)
+newpath 294 360 moveto
+309 351 325 339 335 324 curveto
+347 306 351 281 353 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 356 262 moveto
+354 252 lineto
+350 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 356 262 moveto
+354 252 lineto
+350 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 210 252 moveto
+116 252 lineto
+116 216 lineto
+210 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 210 252 moveto
+116 252 lineto
+116 216 lineto
+210 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+123 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
+% GradedModule(a:CommutativeRing,b:AbelianMonoid)->SetCategory()
+newpath 163 288 moveto
+163 280 163 271 163 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 167 262 moveto
+163 252 lineto
+160 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 167 262 moveto
+163 252 lineto
+160 262 lineto
+closepath
+stroke
+end grestore
+% RetractableTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 424 180 moveto
+284 180 lineto
+284 144 lineto
+424 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 424 180 moveto
+284 180 lineto
+284 144 lineto
+424 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+291 157 moveto
+(RetractableTo\(a:Type\))
+[9.12 6 3.84 4.8 6.24 6.24 4.08 6.24 6.96 3.84 6.24 7.44 6.96 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
+xshow
+end grestore
+end grestore
+% RetractableTo(CommutativeRing)->RetractableTo(a:Type)
+newpath 354 216 moveto
+354 208 354 199 354 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 358 190 moveto
+354 180 lineto
+351 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 358 190 moveto
+354 180 lineto
+351 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 234 36 moveto
+166 36 lineto
+166 0 lineto
+234 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 234 36 moveto
+166 36 lineto
+166 0 lineto
+234 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+174 13 moveto
+(Category)
+[9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+xshow
+end grestore
+end grestore
+% RetractableTo(a:Type)->Category
+newpath 340 144 moveto
+325 125 300 94 275 72 curveto
+263 61 249 51 236 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 238 39 moveto
+228 36 lineto
+234 45 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 238 39 moveto
+228 36 lineto
+234 45 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 116 108 moveto
+32 108 lineto
+32 72 lineto
+116 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 116 108 moveto
+32 108 lineto
+32 72 lineto
+116 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+39 85 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 130 216 moveto
+117 207 102 195 93 180 curveto
+82 162 78 137 75 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 78 118 moveto
+74 108 lineto
+72 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 78 118 moveto
+74 108 lineto
+72 118 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 266 180 moveto
+102 180 lineto
+102 144 lineto
+266 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 266 180 moveto
+102 180 lineto
+102 144 lineto
+266 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+110 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 168 216 moveto
+171 208 174 199 176 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 179 191 moveto
+179 180 lineto
+173 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 179 191 moveto
+179 180 lineto
+173 189 lineto
+closepath
+stroke
+end grestore
+% BasicType()->Category
+newpath 106 72 moveto
+122 63 142 51 160 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 162 44 moveto
+169 36 lineto
+159 38 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 162 44 moveto
+169 36 lineto
+159 38 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 266 108 moveto
+134 108 lineto
+134 72 lineto
+266 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 266 108 moveto
+134 108 lineto
+134 72 lineto
+266 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+142 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 188 144 moveto
+190 136 192 127 194 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 197 118 moveto
+196 108 lineto
+191 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 197 118 moveto
+196 108 lineto
+191 117 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 200 72 moveto
+200 64 200 55 200 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 204 46 moveto
+200 36 lineto
+197 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 204 46 moveto
+200 36 lineto
+197 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102gradedmodule.ps b/books/ps/v102gradedmodule.ps
new file mode 100644
index 0000000..10884c3
--- /dev/null
+++ b/books/ps/v102gradedmodule.ps
@@ -0,0 +1,494 @@
+%!PS-Adobe-2.0
+%%Creator: dot version 2.8 (Thu Sep 14 20:34:11 UTC 2006)
+%%For: (root) root
+%%Title: pic
+%%Pages: (atend)
+%%BoundingBox: 36 36 370 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 370 368
+%%PageOrientation: Portrait
+gsave
+36 36 334 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
+332 330 lineto
+332 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+332 330 lineto
+332 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% GradedModule(a:CommutativeRing,b:AbelianMonoid)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 326 324 moveto
+0 324 lineto
+0 288 lineto
+326 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 326 324 moveto
+0 324 lineto
+0 288 lineto
+326 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+8 301 moveto
+(GradedModule\(a:CommutativeRing,b:AbelianMonoid\))
+[10.08 4.8 6.24 6.96 6.24 6.96 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.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 210 252 moveto
+116 252 lineto
+116 216 lineto
+210 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 210 252 moveto
+116 252 lineto
+116 216 lineto
+210 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+123 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
+% GradedModule(a:CommutativeRing,b:AbelianMonoid)->SetCategory()
+newpath 163 288 moveto
+163 280 163 271 163 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 167 262 moveto
+163 252 lineto
+160 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 167 262 moveto
+163 252 lineto
+160 262 lineto
+closepath
+stroke
+end grestore
+% BasicType()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 142 108 moveto
+58 108 lineto
+58 72 lineto
+142 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 142 108 moveto
+58 108 lineto
+58 72 lineto
+142 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+65 85 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 151 216 moveto
+144 206 136 192 131 180 curveto
+122 160 113 136 108 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 111 117 moveto
+105 108 lineto
+105 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 111 117 moveto
+105 108 lineto
+105 119 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(OutputForm)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 304 180 moveto
+140 180 lineto
+140 144 lineto
+304 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 304 180 moveto
+140 180 lineto
+140 144 lineto
+304 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+148 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 178 216 moveto
+185 207 193 197 201 188 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 204 190 moveto
+207 180 lineto
+198 186 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 204 190 moveto
+207 180 lineto
+198 186 lineto
+closepath
+stroke
+end grestore
+% Category
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 197 36 moveto
+129 36 lineto
+129 0 lineto
+197 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 197 36 moveto
+129 36 lineto
+129 0 lineto
+197 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+137 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 116 72 moveto
+124 63 133 53 140 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 143 46 moveto
+147 36 lineto
+138 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 143 46 moveto
+147 36 lineto
+138 41 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 292 108 moveto
+160 108 lineto
+160 72 lineto
+292 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 292 108 moveto
+160 108 lineto
+160 72 lineto
+292 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+168 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 223 144 moveto
+224 136 224 127 224 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 227 118 moveto
+225 108 lineto
+221 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 227 118 moveto
+225 108 lineto
+221 118 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 210 72 moveto
+202 63 193 53 186 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 188 41 moveto
+179 36 lineto
+183 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 188 41 moveto
+179 36 lineto
+183 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102monad.ps b/books/ps/v102monad.ps
new file mode 100644
index 0000000..535d051
--- /dev/null
+++ b/books/ps/v102monad.ps
@@ -0,0 +1,632 @@
+%!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 514 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 514 368
+%%PageOrientation: Portrait
+gsave
+36 36 478 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
+476 330 lineto
+476 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+476 330 lineto
+476 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 285 324 moveto
+219 324 lineto
+219 288 lineto
+285 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 285 324 moveto
+219 324 lineto
+219 288 lineto
+285 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+227 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 211 252 moveto
+117 252 lineto
+117 216 lineto
+211 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 211 252 moveto
+117 252 lineto
+117 216 lineto
+211 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+124 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
+% Monad()->SetCategory()
+newpath 230 288 moveto
+219 279 206 268 194 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 196 255 moveto
+186 252 lineto
+192 261 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 196 255 moveto
+186 252 lineto
+192 261 lineto
+closepath
+stroke
+end grestore
+% RepeatedSquaring(Monad)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 424 252 moveto
+256 252 lineto
+256 216 lineto
+424 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 424 252 moveto
+256 252 lineto
+256 216 lineto
+424 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+264 229 moveto
+(RepeatedSquaring\(Monad\))
+[9.12 6.24 6.96 6.24 6.24 3.84 6.24 6.96 7.68 6.72 6.96 6.24 5.04 3.84 6.96 6.96 4.56 12.48 6.96 6.96 6.24 6.96 4.56]
+xshow
+end grestore
+end grestore
+% Monad()->RepeatedSquaring(Monad)
+newpath 274 288 moveto
+285 279 298 268 310 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 312 261 moveto
+318 252 lineto
+308 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 312 261 moveto
+318 252 lineto
+308 255 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 84 108 moveto
+0 108 lineto
+0 72 lineto
+84 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 84 108 moveto
+0 108 lineto
+0 72 lineto
+84 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 85 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 121 216 moveto
+104 207 86 195 73 180 curveto
+59 162 51 137 47 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 50 117 moveto
+45 108 lineto
+44 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 50 117 moveto
+45 108 lineto
+44 118 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 246 180 moveto
+82 180 lineto
+82 144 lineto
+246 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 246 180 moveto
+82 180 lineto
+82 144 lineto
+246 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+90 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 164 216 moveto
+164 208 164 199 164 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 168 190 moveto
+164 180 lineto
+161 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 168 190 moveto
+164 180 lineto
+161 190 lineto
+closepath
+stroke
+end grestore
+% RepeatedSquaring(a:SetCategory)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 470 180 moveto
+264 180 lineto
+264 144 lineto
+470 144 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 470 180 moveto
+264 180 lineto
+264 144 lineto
+470 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+271 157 moveto
+(RepeatedSquaring\(a:SetCategory\))
+[9.12 6.24 6.96 6.24 6.24 3.84 6.24 6.96 7.68 6.72 6.96 6.24 5.04 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
+% RepeatedSquaring(Monad)->RepeatedSquaring(a:SetCategory)
+newpath 347 216 moveto
+350 208 353 198 357 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 360 191 moveto
+360 180 lineto
+354 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 360 191 moveto
+360 180 lineto
+354 189 lineto
+closepath
+stroke
+end grestore
+% Package
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 398 108 moveto
+336 108 lineto
+336 72 lineto
+398 72 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 398 108 moveto
+336 108 lineto
+336 72 lineto
+398 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+343 85 moveto
+(Package)
+[7.44 6.24 6 6.96 6.24 6.72 6.24]
+xshow
+end grestore
+end grestore
+% RepeatedSquaring(a:SetCategory)->Package
+newpath 367 144 moveto
+367 136 367 127 367 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 371 118 moveto
+367 108 lineto
+364 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 371 118 moveto
+367 108 lineto
+364 118 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 139 36 moveto
+71 36 lineto
+71 0 lineto
+139 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 139 36 moveto
+71 36 lineto
+71 0 lineto
+139 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+79 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 58 72 moveto
+66 63 75 53 82 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 85 46 moveto
+89 36 lineto
+80 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 85 46 moveto
+89 36 lineto
+80 41 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 234 108 moveto
+102 108 lineto
+102 72 lineto
+234 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 234 108 moveto
+102 108 lineto
+102 72 lineto
+234 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+110 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 165 144 moveto
+166 136 166 127 166 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 169 118 moveto
+167 108 lineto
+163 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 169 118 moveto
+167 108 lineto
+163 118 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 152 72 moveto
+144 63 135 53 128 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 130 41 moveto
+121 36 lineto
+125 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 130 41 moveto
+121 36 lineto
+125 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102monadwithunit.ps b/books/ps/v102monadwithunit.ps
new file mode 100644
index 0000000..1782c9a
--- /dev/null
+++ b/books/ps/v102monadwithunit.ps
@@ -0,0 +1,678 @@
+%!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 514 440
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+	dup 1 exch div /InvScaleFactor exch def
+	dup scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+%%Page: 1 1
+%%PageBoundingBox: 36 36 514 440
+%%PageOrientation: Portrait
+gsave
+36 36 478 404 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+476 402 lineto
+476 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+476 402 lineto
+476 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% MonadWithUnit()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 311 396 moveto
+193 396 lineto
+193 360 lineto
+311 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 311 396 moveto
+193 396 lineto
+193 360 lineto
+311 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+201 373 moveto
+(MonadWithUnit\(\))
+[12.48 6.96 6.96 6.24 6.96 12.96 3.84 4.08 6.96 9.6 6.96 3.84 3.84 4.56 4.56]
+xshow
+end grestore
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 285 324 moveto
+219 324 lineto
+219 288 lineto
+285 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 285 324 moveto
+219 324 lineto
+219 288 lineto
+285 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+227 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% MonadWithUnit()->Monad()
+newpath 252 360 moveto
+252 352 252 343 252 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 256 334 moveto
+252 324 lineto
+249 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 256 334 moveto
+252 324 lineto
+249 334 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 211 252 moveto
+117 252 lineto
+117 216 lineto
+211 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 211 252 moveto
+117 252 lineto
+117 216 lineto
+211 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+124 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
+% Monad()->SetCategory()
+newpath 230 288 moveto
+219 279 206 268 194 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 196 255 moveto
+186 252 lineto
+192 261 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 196 255 moveto
+186 252 lineto
+192 261 lineto
+closepath
+stroke
+end grestore
+% RepeatedSquaring(Monad)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 424 252 moveto
+256 252 lineto
+256 216 lineto
+424 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 424 252 moveto
+256 252 lineto
+256 216 lineto
+424 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+264 229 moveto
+(RepeatedSquaring\(Monad\))
+[9.12 6.24 6.96 6.24 6.24 3.84 6.24 6.96 7.68 6.72 6.96 6.24 5.04 3.84 6.96 6.96 4.56 12.48 6.96 6.96 6.24 6.96 4.56]
+xshow
+end grestore
+end grestore
+% Monad()->RepeatedSquaring(Monad)
+newpath 274 288 moveto
+285 279 298 268 310 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 312 261 moveto
+318 252 lineto
+308 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 312 261 moveto
+318 252 lineto
+308 255 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 84 108 moveto
+0 108 lineto
+0 72 lineto
+84 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 84 108 moveto
+0 108 lineto
+0 72 lineto
+84 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+7 85 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 121 216 moveto
+104 207 86 195 73 180 curveto
+59 162 51 137 47 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 50 117 moveto
+45 108 lineto
+44 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 50 117 moveto
+45 108 lineto
+44 118 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 246 180 moveto
+82 180 lineto
+82 144 lineto
+246 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 246 180 moveto
+82 180 lineto
+82 144 lineto
+246 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+90 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 164 216 moveto
+164 208 164 199 164 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 168 190 moveto
+164 180 lineto
+161 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 168 190 moveto
+164 180 lineto
+161 190 lineto
+closepath
+stroke
+end grestore
+% RepeatedSquaring(a:SetCategory)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 470 180 moveto
+264 180 lineto
+264 144 lineto
+470 144 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 470 180 moveto
+264 180 lineto
+264 144 lineto
+470 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+271 157 moveto
+(RepeatedSquaring\(a:SetCategory\))
+[9.12 6.24 6.96 6.24 6.24 3.84 6.24 6.96 7.68 6.72 6.96 6.24 5.04 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
+% RepeatedSquaring(Monad)->RepeatedSquaring(a:SetCategory)
+newpath 347 216 moveto
+350 208 353 198 357 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 360 191 moveto
+360 180 lineto
+354 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 360 191 moveto
+360 180 lineto
+354 189 lineto
+closepath
+stroke
+end grestore
+% Package
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 398 108 moveto
+336 108 lineto
+336 72 lineto
+398 72 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 398 108 moveto
+336 108 lineto
+336 72 lineto
+398 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+343 85 moveto
+(Package)
+[7.44 6.24 6 6.96 6.24 6.72 6.24]
+xshow
+end grestore
+end grestore
+% RepeatedSquaring(a:SetCategory)->Package
+newpath 367 144 moveto
+367 136 367 127 367 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 371 118 moveto
+367 108 lineto
+364 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 371 118 moveto
+367 108 lineto
+364 118 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 139 36 moveto
+71 36 lineto
+71 0 lineto
+139 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 139 36 moveto
+71 36 lineto
+71 0 lineto
+139 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+79 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 58 72 moveto
+66 63 75 53 82 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 85 46 moveto
+89 36 lineto
+80 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 85 46 moveto
+89 36 lineto
+80 41 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 234 108 moveto
+102 108 lineto
+102 72 lineto
+234 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 234 108 moveto
+102 108 lineto
+102 72 lineto
+234 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+110 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 165 144 moveto
+166 136 166 127 166 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 169 118 moveto
+167 108 lineto
+163 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 169 118 moveto
+167 108 lineto
+163 118 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 152 72 moveto
+144 63 135 53 128 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 130 41 moveto
+121 36 lineto
+125 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 130 41 moveto
+121 36 lineto
+125 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102nonassociativealgebra.ps b/books/ps/v102nonassociativealgebra.ps
new file mode 100644
index 0000000..e41704b
--- /dev/null
+++ b/books/ps/v102nonassociativealgebra.ps
@@ -0,0 +1,838 @@
+%!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 498 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 498 512
+%%PageOrientation: Portrait
+gsave
+36 36 462 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
+460 474 lineto
+460 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+460 474 lineto
+460 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% NonAssociativeAlgebra()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 260 468 moveto
+100 468 lineto
+100 432 lineto
+260 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 260 468 moveto
+100 468 lineto
+100 432 lineto
+260 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+108 445 moveto
+(NonAssociativeAlgebra\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 10.08 3.84 6.72 6.24 6.96 4.8 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 151 396 moveto
+13 396 lineto
+13 360 lineto
+151 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+20 373 moveto
+(NonAssociativeRng\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeAlgebra()->NonAssociativeRng()
+newpath 155 432 moveto
+143 423 128 412 114 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 116 399 moveto
+106 396 lineto
+112 405 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 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 370 396 moveto
+188 396 lineto
+188 360 lineto
+370 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+195 373 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
+% NonAssociativeAlgebra()->Module(a:CommutativeRing)
+newpath 205 432 moveto
+217 423 232 412 246 402 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 248 405 moveto
+254 396 lineto
+244 399 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 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 197 36 moveto
+107 36 lineto
+107 0 lineto
+197 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+114 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
+% NonAssociativeRng()->ABELGRP...
+newpath 65 360 moveto
+57 350 47 337 40 324 curveto
+21 286 11 276 10 234 curveto
+10 234 10 234 10 162 curveto
+11 107 64 65 105 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 107 44 moveto
+114 36 lineto
+104 38 lineto
+closepath
+stroke
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 115 324 moveto
+49 324 lineto
+49 288 lineto
+115 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+57 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()->Monad()
+newpath 82 360 moveto
+82 352 82 343 82 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 86 334 moveto
+82 324 lineto
+79 334 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 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 454 324 moveto
+142 324 lineto
+142 288 lineto
+454 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+149 301 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 284 360 moveto
+286 352 288 343 290 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 293 335 moveto
+293 324 lineto
+287 333 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 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 116 252 moveto
+38 252 lineto
+38 216 lineto
+116 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+46 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
+% Monad()->SETCAT...
+newpath 81 288 moveto
+80 280 80 271 79 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 82 262 moveto
+78 252 lineto
+76 262 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 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 204 252 moveto
+134 252 lineto
+134 216 lineto
+204 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+141 229 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Monad()->REPSQ...
+newpath 104 288 moveto
+115 279 128 268 139 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 141 261 moveto
+147 252 lineto
+137 255 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 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 384 252 moveto
+222 252 lineto
+222 216 lineto
+384 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+230 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
+% BiModule(a:CommutativeRing,b:CommutativeRing)->BiModule(a:Ring,b:Ring)
+newpath 299 288 moveto
+300 280 300 271 301 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 304 262 moveto
+302 252 lineto
+298 262 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 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 217 180 moveto
+87 180 lineto
+87 144 lineto
+217 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+95 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 265 216 moveto
+245 206 220 195 199 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 182 moveto
+190 180 lineto
+197 188 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 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 371 180 moveto
+235 180 lineto
+235 144 lineto
+371 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 303 216 moveto
+303 208 303 199 303 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 307 190 moveto
+303 180 lineto
+300 190 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 215 108 moveto
+89 108 lineto
+89 72 lineto
+215 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+97 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 152 144 moveto
+152 136 152 127 152 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 118 moveto
+152 108 lineto
+149 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 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 368 108 moveto
+234 108 lineto
+234 72 lineto
+368 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+242 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 302 144 moveto
+302 136 302 127 302 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 305 118 moveto
+301 108 lineto
+299 118 lineto
+closepath
+stroke
+end grestore
+% RightModule(a:Rng)->ABELGRP...
+newpath 263 72 moveto
+243 62 219 51 198 40 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 200 37 moveto
+189 36 lineto
+197 43 lineto
+closepath
+stroke
+end grestore
+% LeftModule(a:Rng)->ABELGRP...
+newpath 152 72 moveto
+152 64 152 55 152 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 156 46 moveto
+152 36 lineto
+149 46 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102nonassociativering.ps b/books/ps/v102nonassociativering.ps
new file mode 100644
index 0000000..d72067f
--- /dev/null
+++ b/books/ps/v102nonassociativering.ps
@@ -0,0 +1,771 @@
+%!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 402 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 402 512
+%%PageOrientation: Portrait
+gsave
+36 36 366 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
+364 474 lineto
+364 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 474 lineto
+364 474 lineto
+364 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% NonAssociativeRing()
+[ /Rect [ 74 432 216 468 ]
+  /Border [ 0 0 0 ]
+  /Action << /Subtype /URI /URI (bookvol10.2.pdf#nameddest=NASRING) >>
+  /Subtype /Link
+/ANN pdfmark
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 216 468 moveto
+74 468 lineto
+74 432 lineto
+216 432 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 216 468 moveto
+74 468 lineto
+74 432 lineto
+216 432 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+82 445 moveto
+(NonAssociativeRing\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 3.84 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 287 396 moveto
+149 396 lineto
+149 360 lineto
+287 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 287 396 moveto
+149 396 lineto
+149 360 lineto
+287 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+156 373 moveto
+(NonAssociativeRng\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRing()->NonAssociativeRng()
+newpath 163 432 moveto
+172 423 183 413 193 403 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 195 406 moveto
+200 396 lineto
+190 401 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 195 406 moveto
+200 396 lineto
+190 401 lineto
+closepath
+stroke
+end grestore
+% MonadWithUnit()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 131 396 moveto
+13 396 lineto
+13 360 lineto
+131 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 131 396 moveto
+13 396 lineto
+13 360 lineto
+131 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+21 373 moveto
+(MonadWithUnit\(\))
+[12.48 6.96 6.96 6.24 6.96 12.96 3.84 4.08 6.96 9.6 6.96 3.84 3.84 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRing()->MonadWithUnit()
+newpath 127 432 moveto
+118 423 107 413 97 403 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 100 401 moveto
+90 396 lineto
+95 406 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 100 401 moveto
+90 396 lineto
+95 406 lineto
+closepath
+stroke
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 105 324 moveto
+39 324 lineto
+39 288 lineto
+105 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 105 324 moveto
+39 324 lineto
+39 288 lineto
+105 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+47 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()->Monad()
+newpath 181 360 moveto
+161 350 136 338 114 327 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 116 324 moveto
+105 323 lineto
+113 330 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 116 324 moveto
+105 323 lineto
+113 330 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 271 324 moveto
+165 324 lineto
+165 288 lineto
+271 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 271 324 moveto
+165 324 lineto
+165 288 lineto
+271 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+173 301 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
+% NonAssociativeRng()->AbelianGroup()
+newpath 218 360 moveto
+218 352 218 343 218 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 222 334 moveto
+218 324 lineto
+215 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 222 334 moveto
+218 324 lineto
+215 334 lineto
+closepath
+stroke
+end grestore
+% MonadWithUnit()->Monad()
+newpath 72 360 moveto
+72 352 72 343 72 334 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 76 334 moveto
+72 324 lineto
+69 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 76 334 moveto
+72 324 lineto
+69 334 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 167 36 moveto
+89 36 lineto
+89 0 lineto
+167 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 167 36 moveto
+89 36 lineto
+89 0 lineto
+167 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+97 13 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
+% Monad()->SETCAT...
+newpath 53 288 moveto
+44 278 34 265 29 252 curveto
+24 236 26 231 29 216 curveto
+45 151 86 82 109 45 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 112 46 moveto
+115 36 lineto
+107 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 112 46 moveto
+115 36 lineto
+107 42 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 108 252 moveto
+38 252 lineto
+38 216 lineto
+108 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 108 252 moveto
+38 252 lineto
+38 216 lineto
+108 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+45 229 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Monad()->REPSQ...
+newpath 72 288 moveto
+73 280 73 271 73 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 77 262 moveto
+73 252 lineto
+70 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 77 262 moveto
+73 252 lineto
+70 262 lineto
+closepath
+stroke
+end grestore
+% CancellationAbelianMonoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 310 252 moveto
+126 252 lineto
+126 216 lineto
+310 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 310 252 moveto
+126 252 lineto
+126 216 lineto
+310 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+134 229 moveto
+(CancellationAbelianMonoid\(\))
+[9.36 6.24 6.96 6.24 6.24 3.84 3.84 6.24 3.84 3.84 6.96 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->CancellationAbelianMonoid()
+newpath 218 288 moveto
+218 280 218 271 218 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 222 262 moveto
+218 252 lineto
+215 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 222 262 moveto
+218 252 lineto
+215 262 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 314 36 moveto
+242 36 lineto
+242 0 lineto
+314 0 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 314 36 moveto
+242 36 lineto
+242 0 lineto
+314 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+249 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 271 290 moveto
+289 282 308 269 319 252 curveto
+358 186 318 91 294 45 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 297 43 moveto
+289 36 lineto
+291 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 297 43 moveto
+289 36 lineto
+291 46 lineto
+closepath
+stroke
+end grestore
+% AbelianMonoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 275 180 moveto
+161 180 lineto
+161 144 lineto
+275 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 275 180 moveto
+161 180 lineto
+161 144 lineto
+275 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+168 157 moveto
+(AbelianMonoid\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% CancellationAbelianMonoid()->AbelianMonoid()
+newpath 218 216 moveto
+218 208 218 199 218 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 222 190 moveto
+218 180 lineto
+215 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 222 190 moveto
+218 180 lineto
+215 190 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 285 108 moveto
+151 108 lineto
+151 72 lineto
+285 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 285 108 moveto
+151 108 lineto
+151 72 lineto
+285 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+158 85 moveto
+(AbelianSemiGroup\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 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
+% AbelianMonoid()->AbelianSemiGroup()
+newpath 218 144 moveto
+218 136 218 127 218 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 222 118 moveto
+218 108 lineto
+215 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 222 118 moveto
+218 108 lineto
+215 118 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()->SETCAT...
+newpath 195 72 moveto
+184 63 170 52 158 42 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 160 39 moveto
+150 36 lineto
+156 45 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 160 39 moveto
+150 36 lineto
+156 45 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()->REPDB...
+newpath 233 72 moveto
+240 63 249 53 256 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 259 46 moveto
+263 36 lineto
+254 41 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 259 46 moveto
+263 36 lineto
+254 41 lineto
+closepath
+stroke
+end grestore
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/books/ps/v102nonassociativerng.ps b/books/ps/v102nonassociativerng.ps
new file mode 100644
index 0000000..c696cfc
--- /dev/null
+++ b/books/ps/v102nonassociativerng.ps
@@ -0,0 +1,653 @@
+%!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 402 440
+%%EndComments
+save
+%%BeginProlog
+/DotDict 200 dict def
+DotDict begin
+
+/setupLatin1 {
+mark
+/EncodingVector 256 array def
+ EncodingVector 0
+
+ISOLatin1Encoding 0 255 getinterval putinterval
+EncodingVector 45 /hyphen put
+
+% Set up ISO Latin 1 character encoding
+/starnetISO {
+        dup dup findfont dup length dict begin
+        { 1 index /FID ne { def }{ pop pop } ifelse
+        } forall
+        /Encoding EncodingVector def
+        currentdict end definefont
+} def
+/Times-Roman starnetISO def
+/Times-Italic starnetISO def
+/Times-Bold starnetISO def
+/Times-BoldItalic starnetISO def
+/Helvetica starnetISO def
+/Helvetica-Oblique starnetISO def
+/Helvetica-Bold starnetISO def
+/Helvetica-BoldOblique starnetISO def
+/Courier starnetISO def
+/Courier-Oblique starnetISO def
+/Courier-Bold starnetISO def
+/Courier-BoldOblique starnetISO def
+cleartomark
+} bind def
+
+%%BeginResource: procset graphviz 0 0
+/coord-font-family /Times-Roman def
+/default-font-family /Times-Roman def
+/coordfont coord-font-family findfont 8 scalefont def
+
+/InvScaleFactor 1.0 def
+/set_scale {
+	dup 1 exch div /InvScaleFactor exch def
+	dup scale
+} bind def
+
+% styles
+/solid { [] 0 setdash } bind def
+/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
+/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
+/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
+/bold { 2 setlinewidth } bind def
+/filled { } bind def
+/unfilled { } bind def
+/rounded { } bind def
+/diagonals { } bind def
+
+% hooks for setting color 
+/nodecolor { sethsbcolor } bind def
+/edgecolor { sethsbcolor } bind def
+/graphcolor { sethsbcolor } bind def
+/nopcolor {pop pop pop} bind def
+
+/beginpage {	% i j npages
+	/npages exch def
+	/j exch def
+	/i exch def
+	/str 10 string def
+	npages 1 gt {
+		gsave
+			coordfont setfont
+			0 0 moveto
+			(\() show i str cvs show (,) show j str cvs show (\)) show
+		grestore
+	} if
+} bind def
+
+/set_font {
+	findfont exch
+	scalefont setfont
+} def
+
+% draw aligned label in bounding box aligned to current point
+/alignedtext {			% width adj text
+	/text exch def
+	/adj exch def
+	/width exch def
+	gsave
+		width 0 gt {
+			text stringwidth pop adj mul 0 rmoveto
+		} if
+		[] 0 setdash
+		text show
+	grestore
+} def
+
+/boxprim {				% xcorner ycorner xsize ysize
+		4 2 roll
+		moveto
+		2 copy
+		exch 0 rlineto
+		0 exch rlineto
+		pop neg 0 rlineto
+		closepath
+} bind def
+
+/ellipse_path {
+	/ry exch def
+	/rx exch def
+	/y exch def
+	/x exch def
+	matrix currentmatrix
+	newpath
+	x y translate
+	rx ry scale
+	0 0 1 0 360 arc
+	setmatrix
+} bind def
+
+/endpage { showpage } bind def
+/showpage { } def
+
+/layercolorseq
+	[	% layer color sequence - darkest to lightest
+		[0 0 0]
+		[.2 .8 .8]
+		[.4 .8 .8]
+		[.6 .8 .8]
+		[.8 .8 .8]
+	]
+def
+
+/layerlen layercolorseq length def
+
+/setlayer {/maxlayer exch def /curlayer exch def
+	layercolorseq curlayer 1 sub layerlen mod get
+	aload pop sethsbcolor
+	/nodecolor {nopcolor} def
+	/edgecolor {nopcolor} def
+	/graphcolor {nopcolor} def
+} bind def
+
+/onlayer { curlayer ne {invis} if } def
+
+/onlayers {
+	/myupper exch def
+	/mylower exch def
+	curlayer mylower lt
+	curlayer myupper gt
+	or
+	{invis} if
+} def
+
+/curlayer 0 def
+
+%%EndResource
+%%EndProlog
+%%BeginSetup
+14 default-font-family set_font
+1 setmiterlimit
+% /arrowlength 10 def
+% /arrowwidth 5 def
+
+% make sure pdfmark is harmless for PS-interpreters other than Distiller
+/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
+% make '<<' and '>>' safe on PS Level 1 devices
+/languagelevel where {pop languagelevel}{1} ifelse
+2 lt {
+    userdict (<<) cvn ([) cvn load put
+    userdict (>>) cvn ([) cvn load put
+} if
+
+%%EndSetup
+%%Page: 1 1
+%%PageBoundingBox: 36 36 402 440
+%%PageOrientation: Portrait
+gsave
+36 36 366 404 boxprim clip newpath
+36 36 translate
+0 0 1 beginpage
+1.0000 set_scale
+4 4 translate 0 rotate
+0.167 0.600 1.000 graphcolor
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+364 402 lineto
+364 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 402 lineto
+364 402 lineto
+364 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% NonAssociativeRng()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 269 396 moveto
+131 396 lineto
+131 360 lineto
+269 360 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 269 396 moveto
+131 396 lineto
+131 360 lineto
+269 360 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+138 373 moveto
+(NonAssociativeRng\(\))
+[9.84 6.96 6.96 10.08 5.52 5.52 6.96 6.24 3.84 6.24 3.84 3.84 6.48 6.24 9.36 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% AbelianGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 193 324 moveto
+87 324 lineto
+87 288 lineto
+193 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 193 324 moveto
+87 324 lineto
+87 288 lineto
+193 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+95 301 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
+% NonAssociativeRng()->AbelianGroup()
+newpath 185 360 moveto
+178 351 169 341 162 332 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 164 329 moveto
+155 324 lineto
+159 334 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 164 329 moveto
+155 324 lineto
+159 334 lineto
+closepath
+stroke
+end grestore
+% Monad()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 293 324 moveto
+227 324 lineto
+227 288 lineto
+293 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 293 324 moveto
+227 324 lineto
+227 288 lineto
+293 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+235 301 moveto
+(Monad\(\))
+[12.48 6.96 6.96 6.24 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% NonAssociativeRng()->Monad()
+newpath 215 360 moveto
+222 351 231 341 238 332 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 241 334 moveto
+245 324 lineto
+236 329 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 241 334 moveto
+245 324 lineto
+236 329 lineto
+closepath
+stroke
+end grestore
+% CancellationAbelianMonoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 232 252 moveto
+48 252 lineto
+48 216 lineto
+232 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 232 252 moveto
+48 252 lineto
+48 216 lineto
+232 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+56 229 moveto
+(CancellationAbelianMonoid\(\))
+[9.36 6.24 6.96 6.24 6.24 3.84 3.84 6.24 3.84 3.84 6.96 6.96 9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% AbelianGroup()->CancellationAbelianMonoid()
+newpath 140 288 moveto
+140 280 140 271 140 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 144 262 moveto
+140 252 lineto
+137 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 144 262 moveto
+140 252 lineto
+137 262 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 123 36 moveto
+51 36 lineto
+51 0 lineto
+123 0 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 123 36 moveto
+51 36 lineto
+51 0 lineto
+123 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+58 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 87 290 moveto
+68 282 50 270 39 252 curveto
+0 185 44 90 70 45 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 73 46 moveto
+75 36 lineto
+67 43 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 73 46 moveto
+75 36 lineto
+67 43 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 232 36 moveto
+154 36 lineto
+154 0 lineto
+232 0 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 232 36 moveto
+154 36 lineto
+154 0 lineto
+232 0 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+162 13 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
+% Monad()->SETCAT...
+newpath 258 288 moveto
+253 248 239 150 216 72 curveto
+213 63 209 54 206 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 209 44 moveto
+202 36 lineto
+202 47 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 209 44 moveto
+202 36 lineto
+202 47 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 358 252 moveto
+288 252 lineto
+288 216 lineto
+358 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 358 252 moveto
+288 252 lineto
+288 216 lineto
+358 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+295 229 moveto
+(REPSQ...)
+[9.36 8.64 7.68 7.68 10.08 3.6 3.6 3.6]
+xshow
+end grestore
+end grestore
+% Monad()->REPSQ...
+newpath 276 288 moveto
+284 279 293 269 300 260 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 303 262 moveto
+307 252 lineto
+298 257 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 303 262 moveto
+307 252 lineto
+298 257 lineto
+closepath
+stroke
+end grestore
+% AbelianMonoid()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 197 180 moveto
+83 180 lineto
+83 144 lineto
+197 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 197 180 moveto
+83 180 lineto
+83 144 lineto
+197 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+90 157 moveto
+(AbelianMonoid\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 12.48 6.96 6.96 6.96 3.84 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% CancellationAbelianMonoid()->AbelianMonoid()
+newpath 140 216 moveto
+140 208 140 199 140 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 144 190 moveto
+140 180 lineto
+137 190 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 144 190 moveto
+140 180 lineto
+137 190 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 207 108 moveto
+73 108 lineto
+73 72 lineto
+207 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 207 108 moveto
+73 108 lineto
+73 72 lineto
+207 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+80 85 moveto
+(AbelianSemiGroup\(\))
+[9.84 6.96 6.24 3.84 3.84 6.24 6.96 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
+% AbelianMonoid()->AbelianSemiGroup()
+newpath 140 144 moveto
+140 136 140 127 140 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 144 118 moveto
+140 108 lineto
+137 118 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 144 118 moveto
+140 108 lineto
+137 118 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()->SETCAT...
+newpath 153 72 moveto
+159 64 167 53 174 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 177 46 moveto
+180 36 lineto
+171 42 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 177 46 moveto
+180 36 lineto
+171 42 lineto
+closepath
+stroke
+end grestore
+% AbelianSemiGroup()->REPDB...
+newpath 127 72 moveto
+121 64 113 53 106 44 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 109 42 moveto
+100 36 lineto
+103 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 109 42 moveto
+100 36 lineto
+103 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 e1e48d8..1f17334 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,8 @@
+20080927 tpd src/algebra/Makefile remove naalgc
+20080927 tpd books/bookvol10.2 add categories
+20080927 tpd src/algebra/naalgc.spad absorbed into bookvol10.2
+20080927 tpd src/algebra/curve.spad move categories to bookvol10.2
+20080927 tpd src/algebra/carten.spad move categories to bookvol10.2
 20080926 tpd books/bookvol10.2 add attributes
 20080926 tpd src/algebra/Makefile remove attreg
 20080926 tpd books/ps/v102twodimensionalarraycategory.ps added
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
index 81914f5..5c3c9d8 100644
--- a/src/algebra/Makefile.pamphlet
+++ b/src/algebra/Makefile.pamphlet
@@ -803,7 +803,6 @@ mkfunc.spad.pamphlet (INFORM INFORM1 MKFUNC MKUCFUNC MKBCFUNC MKFLCFN)
 modgcd.spad.pamphlet (INMODGCD)
 mset.spad.pamphlet (MSET)
 multpoly.spad.pamphlet (POLY POLY2 MPOLY SMP INDE)
-naalgc.spad.pamphlet (MONAD MONADWU NARNG NASRING NAALG FINAALG FRNAALG)
 newdata.spad.pamphlet (IPRNTPK TBCMPPK SPLNODE SPLTREE)
 omerror.spad.pamphlet (OMERRK OMERR)
 op.spad.pamphlet (BOP BOP1 COMMONOP)
@@ -1253,7 +1252,7 @@ SPADFILES= \
  ${OUTSRC}/moebius.spad ${OUTSRC}/mring.spad ${OUTSRC}/mset.spad \
  ${OUTSRC}/mts.spad ${OUTSRC}/multfact.spad ${OUTSRC}/multpoly.spad \
  ${OUTSRC}/multsqfr.spad \
- ${OUTSRC}/naalgc.spad ${OUTSRC}/naalg.spad \
+ ${OUTSRC}/naalg.spad \
  ${OUTSRC}/newdata.spad ${OUTSRC}/newpoint.spad \
  ${OUTSRC}/newpoly.spad ${OUTSRC}/nlinsol.spad ${OUTSRC}/nlode.spad \
  ${OUTSRC}/npcoef.spad \
@@ -1414,7 +1413,7 @@ DOCFILES= \
  ${DOC}/moebius.spad.dvi ${DOC}/mring.spad.dvi ${DOC}/mset.spad.dvi \
  ${DOC}/mts.spad.dvi ${DOC}/multfact.spad.dvi ${DOC}/multpoly.spad.dvi \
  ${DOC}/multsqfr.spad.dvi \
- ${DOC}/naalgc.spad.dvi ${DOC}/naalg.spad.dvi ${DOC}/ndftip.as.dvi \
+ ${DOC}/naalg.spad.dvi ${DOC}/ndftip.as.dvi \
  ${DOC}/nepip.as.dvi ${DOC}/newdata.spad.dvi ${DOC}/newpoint.spad.dvi \
  ${DOC}/newpoly.spad.dvi ${DOC}/nlinsol.spad.dvi ${DOC}/nlode.spad.dvi \
  ${DOC}/noptip.as.dvi ${DOC}/npcoef.spad.dvi ${DOC}/nqip.as.dvi \
diff --git a/src/algebra/carten.spad.pamphlet b/src/algebra/carten.spad.pamphlet
index 38170aa..1894c2f 100644
--- a/src/algebra/carten.spad.pamphlet
+++ b/src/algebra/carten.spad.pamphlet
@@ -9,110 +9,6 @@
 \eject
 \tableofcontents
 \eject
-\section{category GRMOD GradedModule}
-<<dot>>=
-"GRMOD" -> "SETCAT"
-"GradedModule(a:CommutativeRing,b:AbelianMonoid)" -> "SetCategory()"
-@
-<<category GRMOD GradedModule>>=
-)abbrev category GRMOD GradedModule
-++ Author: Stephen M. Watt
-++ Date Created: May 20, 1991
-++ Date Last Updated: May 20, 1991
-++ Basic Operations: +, *, degree
-++ Related Domains: CartesianTensor(n,dim,R)
-++ Also See:
-++ AMS Classifications:
-++ Keywords: graded module, tensor, multi-linear algebra
-++ Examples:
-++ References: Algebra 2d Edition, MacLane and Birkhoff, MacMillan 1979
-++ Description:
-++  GradedModule(R,E) denotes ``E-graded R-module'', i.e. collection of
-++  R-modules indexed by an abelian monoid E.
-++  An element \spad{g} of \spad{G[s]} for some specific \spad{s} in \spad{E}
-++  is said to be an element of \spad{G} with {\em degree} \spad{s}.
-++  Sums are defined in each module \spad{G[s]} so two elements of \spad{G}
-++  have a sum if they have the same degree.
-++
-++  Morphisms can be defined and composed by degree to give the
-++  mathematical category of graded modules.
-
-GradedModule(R: CommutativeRing, E: AbelianMonoid): Category ==
-    SetCategory with
-        degree: % -> E
-            ++ degree(g) names the degree of g.  The set of all elements
-            ++ of a given degree form an R-module.
-        0: constant -> %
-            ++ 0 denotes the zero of degree 0.
-        _*: (R, %) -> %
-            ++ r*g is left module multiplication.
-        _*: (%, R) -> %
-            ++ g*r is right module multiplication.
-
-        _-: % -> %
-            ++ -g is the additive inverse of g in the module of elements
-            ++ of the same grade as g.
-        _+: (%, %) -> %
-            ++ g+h is the sum of g and h in the module of elements of
-            ++ the same degree as g and h.  Error: if g and h
-            ++ have different degrees.
-        _-: (%, %) -> %
-            ++ g-h is the difference of g and h in the module of elements of
-            ++ the same degree as g and h.  Error: if g and h
-            ++ have different degrees.
-  add
-        (x: %) - (y: %) == x+(-y)
-
-@
-\section{category GRALG GradedAlgebra}
-<<dot>>=
-"GRALG" -> "GRMOD"
-"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
-    "GradedModule(a:CommutativeRing,b:AbelianMonoid)"
-"GRALG" -> "RETRACT"
-"GradedAlgebra(a:CommutativeRing,b:AbelianMonoid)" ->
-    "RetractableTo(CommutativeRing)"
-@
-<<category GRALG GradedAlgebra>>=
-)abbrev category GRALG GradedAlgebra
-++ Author: Stephen M. Watt
-++ Date Created: May 20, 1991
-++ Date Last Updated: May 20, 1991
-++ Basic Operations: +, *, degree
-++ Related Domains: CartesianTensor(n,dim,R)
-++ Also See:
-++ AMS Classifications:
-++ Keywords: graded module, tensor, multi-linear algebra
-++ Examples:
-++ References: Encyclopedic Dictionary of Mathematics, MIT Press, 1977
-++ Description:
-++  GradedAlgebra(R,E) denotes ``E-graded R-algebra''.
-++  A graded algebra is a graded module together with a degree preserving
-++  R-linear map, called the {\em product}.
-++
-++  The name ``product'' is written out in full so inner and outer products
-++  with the same mapping type can be distinguished by name.
-
-GradedAlgebra(R: CommutativeRing, E: AbelianMonoid): Category ==
-    Join(GradedModule(R, E),RetractableTo(R)) with
-        1: constant -> %
-            ++ 1 is the identity for \spad{product}.
-        product: (%, %) -> %
-            ++ product(a,b) is the degree-preserving R-linear product:
-            ++
-            ++   \spad{degree product(a,b) = degree a + degree b}
-            ++   \spad{product(a1+a2,b) = product(a1,b) + product(a2,b)}
-            ++   \spad{product(a,b1+b2) = product(a,b1) + product(a,b2)}
-            ++   \spad{product(r*a,b) = product(a,r*b) = r*product(a,b)}
-            ++   \spad{product(a,product(b,c)) = product(product(a,b),c)}
-  add
-        if not (R is %) then
-            0: % == (0$R)::%
-            1: % == 1$R::%
-            (r: R)*(x: %) == product(r::%, x)
-            (x: %)*(r: R) == product(x, r::%)
-
-@
 \section{domain CARTEN CartesianTensor}
 <<CartesianTensor.input>>=
 -- carten.spad.pamphlet CartesianTensor.input
@@ -1752,8 +1648,6 @@ CartesianTensorFunctions2(minix, dim, S, T): CTPcat == CTPdef where
 <<*>>=
 <<license>>
 
-<<category GRMOD GradedModule>>
-<<category GRALG GradedAlgebra>>
 <<domain CARTEN CartesianTensor>>
 <<package CARTEN2 CartesianTensorFunctions2>>
 @
diff --git a/src/algebra/curve.spad.pamphlet b/src/algebra/curve.spad.pamphlet
index d0b44da..9d4d464 100644
--- a/src/algebra/curve.spad.pamphlet
+++ b/src/algebra/curve.spad.pamphlet
@@ -9,415 +9,15 @@
 \eject
 \tableofcontents
 \eject
-\section{category FFCAT FunctionFieldCategory}
-<<category FFCAT FunctionFieldCategory>>=
-)abbrev category FFCAT FunctionFieldCategory
-++ Function field of a curve
-++ Author: Manuel Bronstein
-++ Date Created: 1987
-++ Date Last Updated: 19 Mai 1993
-++ Description: This category is a model for the function field of a
-++ plane algebraic curve.
-++ Keywords: algebraic, curve, function, field.
-FunctionFieldCategory(F, UP, UPUP): Category == Definition where
-  F   : UniqueFactorizationDomain
-  UP  : UnivariatePolynomialCategory F
-  UPUP: UnivariatePolynomialCategory Fraction UP
-
-  Z   ==> Integer
-  Q   ==> Fraction F
-  P   ==> Polynomial F
-  RF  ==> Fraction UP
-  QF  ==> Fraction UPUP
-  SY  ==> Symbol
-  REC ==> Record(num:$, den:UP, derivden:UP, gd:UP)
-
-  Definition ==> MonogenicAlgebra(RF, UPUP) with
-    numberOfComponents     : () -> NonNegativeInteger
-      ++ numberOfComponents() returns the number of absolutely irreducible
-      ++ components.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X numberOfComponents()$R
-    genus                  : () -> NonNegativeInteger
-      ++ genus() returns the genus of one absolutely irreducible component
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X genus()$R
-    absolutelyIrreducible? : () -> Boolean
-      ++ absolutelyIrreducible?() tests if the curve absolutely irreducible?
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
-      ++X absolutelyIrreducible?()$R2
-    rationalPoint?         : (F, F) -> Boolean
-      ++ rationalPoint?(a, b) tests if \spad{(x=a,y=b)} is on the curve.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X rationalPoint?(0,0)$R
-      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
-      ++X rationalPoint?(0,0)$R2
-    branchPointAtInfinity? : () -> Boolean
-      ++ branchPointAtInfinity?() tests if there is a branch point at infinity.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X branchPointAtInfinity?()$R
-      ++X R2 := RadicalFunctionField(INT, P0, P1, 2 * x**2, 4)
-      ++X branchPointAtInfinity?()$R
-    branchPoint?           : F -> Boolean
-      ++ branchPoint?(a) tests whether \spad{x = a} is a branch point.
-    branchPoint?           : UP -> Boolean
-      ++ branchPoint?(p) tests whether \spad{p(x) = 0} is a branch point.
-    singularAtInfinity?    : () -> Boolean
-      ++ singularAtInfinity?() tests if there is a singularity at infinity.
-    singular?              : F -> Boolean
-      ++ singular?(a) tests whether \spad{x = a} is singular.
-    singular?              : UP -> Boolean
-      ++ singular?(p) tests whether \spad{p(x) = 0} is singular.
-    ramifiedAtInfinity?    : () -> Boolean
-      ++ ramifiedAtInfinity?() tests if infinity is ramified.
-    ramified?              : F -> Boolean
-      ++ ramified?(a) tests whether \spad{x = a} is ramified.
-    ramified?              : UP -> Boolean
-      ++ ramified?(p) tests whether \spad{p(x) = 0} is ramified.
-    integralBasis          : () -> Vector $
-      ++ integralBasis() returns the integral basis for the curve.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X integralBasis()$R
-    integralBasisAtInfinity: () -> Vector $
-      ++ integralBasisAtInfinity() returns the local integral basis at infinity
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X integralBasisAtInfinity()$R
-    integralAtInfinity?    : $  -> Boolean
-      ++ integralAtInfinity?() tests if f is locally integral at infinity.
-    integral?              : $  -> Boolean
-      ++ integral?() tests if f is integral over \spad{k[x]}.
-    complementaryBasis     : Vector $ -> Vector $
-      ++ complementaryBasis(b1,...,bn) returns the complementary basis
-      ++ \spad{(b1',...,bn')} of \spad{(b1,...,bn)}.
-    normalizeAtInfinity    : Vector $ -> Vector $
-      ++ normalizeAtInfinity(v) makes v normal at infinity.
-    reduceBasisAtInfinity  : Vector $ -> Vector $
-      ++ reduceBasisAtInfinity(b1,...,bn) returns \spad{(x**i * bj)}
-      ++ for all i,j such that \spad{x**i*bj} is locally integral at infinity.
-    integralMatrix         : () -> Matrix RF
-      ++ integralMatrix() returns M such that
-      ++ \spad{(w1,...,wn) = M (1, y, ..., y**(n-1))},
-      ++ where \spad{(w1,...,wn)} is the integral basis of
-      ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X integralMatrix()$R
-    inverseIntegralMatrix  : () -> Matrix RF
-      ++ inverseIntegralMatrix() returns M such that
-      ++ \spad{M (w1,...,wn) = (1, y, ..., y**(n-1))}
-      ++ where \spad{(w1,...,wn)} is the integral basis of
-      ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X inverseIntegralMatrix()$R
-    integralMatrixAtInfinity       : () -> Matrix RF
-      ++ integralMatrixAtInfinity() returns M such that
-      ++ \spad{(v1,...,vn) = M (1, y, ..., y**(n-1))}
-      ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
-      ++ returned by \spad{infIntBasis()}.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X integralMatrixAtInfinity()$R
-    inverseIntegralMatrixAtInfinity: () -> Matrix RF
-      ++ inverseIntegralMatrixAtInfinity() returns M such
-      ++ that \spad{M (v1,...,vn) = (1, y, ..., y**(n-1))}
-      ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
-      ++ returned by \spad{infIntBasis()}.
-      ++
-      ++X P0 := UnivariatePolynomial(x, Integer)
-      ++X P1 := UnivariatePolynomial(y, Fraction P0)
-      ++X R := RadicalFunctionField(INT, P0, P1, 1 - x**20, 20)
-      ++X inverseIntegralMatrixAtInfinity()$R
-    yCoordinates           : $ -> Record(num:Vector(UP), den:UP)
-      ++ yCoordinates(f) returns \spad{[[A1,...,An], D]} such that
-      ++ \spad{f = (A1 + A2 y +...+ An y**(n-1)) / D}.
-    represents             : (Vector UP, UP) -> $
-      ++ represents([A0,...,A(n-1)],D) returns
-      ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
-    integralCoordinates    : $ -> Record(num:Vector(UP), den:UP)
-      ++ integralCoordinates(f) returns \spad{[[A1,...,An], D]} such that
-      ++ \spad{f = (A1 w1 +...+ An wn) / D}  where \spad{(w1,...,wn)} is the
-      ++ integral basis returned by \spad{integralBasis()}.
-    integralRepresents     : (Vector UP, UP) -> $
-      ++ integralRepresents([A1,...,An], D) returns
-      ++ \spad{(A1 w1+...+An wn)/D}
-      ++ where \spad{(w1,...,wn)} is the integral
-      ++ basis of \spad{integralBasis()}.
-    integralDerivationMatrix:(UP -> UP) -> Record(num:Matrix(UP),den:UP)
-      ++ integralDerivationMatrix(d) extends the derivation d from UP to $
-      ++ and returns (M, Q) such that the i^th row of M divided by Q form
-      ++ the coordinates of \spad{d(wi)} with respect to \spad{(w1,...,wn)}
-      ++ where \spad{(w1,...,wn)} is the integral basis returned
-      ++ by integralBasis().
-    integral?              : ($,  F) -> Boolean
-      ++ integral?(f, a) tests whether f is locally integral at \spad{x = a}.
-    integral?              : ($, UP) -> Boolean
-      ++ integral?(f, p) tests whether f is locally integral at \spad{p(x) = 0}
-    differentiate          : ($, UP -> UP) -> $
-      ++ differentiate(x, d) extends the derivation d from UP to $ and
-      ++ applies it to x.
-    represents             : (Vector UP, UP) -> $
-      ++ represents([A0,...,A(n-1)],D) returns
-      ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
-    primitivePart          : $ -> $
-      ++ primitivePart(f) removes the content of the denominator and
-      ++ the common content of the numerator of f.
-    elt                    : ($, F, F) -> F
-      ++ elt(f,a,b) or f(a, b) returns the value of f 
-      ++ at the point \spad{(x = a, y = b)}
-      ++ if it is not singular.
-    elliptic               : () -> Union(UP, "failed")
-      ++ elliptic() returns \spad{p(x)} if the curve is the elliptic
-      ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
-    hyperelliptic          : () -> Union(UP, "failed")
-      ++ hyperelliptic() returns \spad{p(x)} if the curve is the hyperelliptic
-      ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
-    algSplitSimple         : ($, UP -> UP) -> REC
-      ++ algSplitSimple(f, D) returns \spad{[h,d,d',g]} such that \spad{f=h/d},
-      ++ \spad{h} is integral at all the normal places w.r.t. \spad{D},
-      ++ \spad{d' = Dd}, \spad{g = gcd(d, discriminant())} and \spad{D}
-      ++ is the derivation to use. \spad{f} must have at most simple finite
-      ++ poles.
-    if F has Field then
-      nonSingularModel: SY -> List Polynomial F
-        ++ nonSingularModel(u) returns the equations in u1,...,un of
-        ++ an affine non-singular model for the curve.
-    if F has Finite then
-      rationalPoints: () -> List List F
-        ++ rationalPoints() returns the list of all the affine rational points.
-
-   add
-    import InnerCommonDenominator(UP, RF, Vector UP, Vector RF)
-    import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
-
-    repOrder: (Matrix RF, Z) -> Z
-    Q2RF    : Q  -> RF
-    infOrder: RF -> Z
-    infValue: RF -> Fraction F
-    intvalue: (Vector UP, F, F) -> F
-    rfmonom : Z  -> RF
-    kmin    : (Matrix RF,Vector Q) -> Union(Record(pos:Z,km:Z),"failed")
-
-    Q2RF q                 == numer(q)::UP / denom(q)::UP
-    infOrder f             == (degree denom f)::Z - (degree numer f)::Z
-    integral? f            == ground?(integralCoordinates(f).den)
-    integral?(f:$, a:F)    == (integralCoordinates(f).den)(a) ^= 0
---    absolutelyIrreducible? == one? numberOfComponents()
-    absolutelyIrreducible? == numberOfComponents() = 1
-    yCoordinates f         == splitDenominator coordinates f
-
-    hyperelliptic() ==
-      degree(f := definingPolynomial()) ^= 2 => "failed"
-      (u:=retractIfCan(reductum f)@Union(RF,"failed")) case "failed" => "failed"
-      (v := retractIfCan(-(u::RF) / leadingCoefficient f)@Union(UP, "failed"))
-        case "failed" => "failed"
-      odd? degree(p := v::UP) => p
-      "failed"
-
-    algSplitSimple(f, derivation) ==
-      cd := splitDenominator lift f
-      dd := (cd.den exquo (g := gcd(cd.den, derivation(cd.den))))::UP
-      [reduce(inv(g::RF) * cd.num), dd, derivation dd,
-                                    gcd(dd, retract(discriminant())@UP)]
-
-    elliptic() ==
-      (u := hyperelliptic()) case "failed" => "failed"
-      degree(p := u::UP) = 3 => p
-      "failed"
-
-    rationalPoint?(x, y)   ==
-      zero?((definingPolynomial() (y::UP::RF)) (x::UP::RF))
-
-    if F has Field then
-      import PolyGroebner(F)
-      import MatrixCommonDenominator(UP, RF)
-
-      UP2P  : (UP,   P)    -> P
-      UPUP2P: (UPUP, P, P) -> P
-
-      UP2P(p, x) ==
-        (map(#1::P, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
-                                     P, SparseUnivariatePolynomial P)) x
-
-      UPUP2P(p, x, y) ==
-        (map(UP2P(retract(#1)@UP, x),
-             p)$UnivariatePolynomialCategoryFunctions2(RF, UPUP,
-                                     P, SparseUnivariatePolynomial P)) y
-
-      nonSingularModel u ==
-        d    := commonDenominator(coordinates(w := integralBasis()))::RF
-        vars := [concat(string u, string i)::SY for i in 1..(n := #w)]
-        x    := "%%dummy1"::SY
-        y    := "%%dummy2"::SY
-        select_!(zero?(degree(#1, x)) and zero?(degree(#1, y)),
-                 lexGroebner([v::P - UPUP2P(lift(d * w.i), x::P, y::P)
-                    for v in vars for i in 1..n], concat([x, y], vars)))
-
-    if F has Finite then
-      ispoint: (UPUP, F, F) -> List F
-
--- must use the 'elt function explicitely or the compiler takes 45 mins
--- on that function    MB 5/90
--- still takes ages : I split the expression up. JHD 6/Aug/90
-      ispoint(p, x, y) ==
-        jhd:RF:=p(y::UP::RF)
-        zero?(jhd (x::UP::RF)) => [x, y]
-        empty()
-
-      rationalPoints() ==
-        p := definingPolynomial()
-        concat [[pt for y in 1..size()$F | not empty?(pt :=
-          ispoint(p, index(x::PositiveInteger)$F,
-                     index(y::PositiveInteger)$F))]$List(List F)
-                                for x in 1..size()$F]$List(List(List F))
-
-    intvalue(v, x, y) ==
-      singular? x => error "Point is singular"
-      mini := minIndex(w := integralBasis())
-      rec := yCoordinates(+/[qelt(v, i)::RF * qelt(w, i)
-                           for i in mini .. maxIndex w])
-      n   := +/[(qelt(rec.num, i) x) *
-                (y ** ((i - mini)::NonNegativeInteger))
-                           for i in mini .. maxIndex w]
-      zero?(d := (rec.den) x) =>
-        zero? n => error "0/0 -- cannot compute value yet"
-        error "Shouldn't happen"
-      (n exquo d)::F
-
-    elt(f, x, y) ==
-      rec := integralCoordinates f
-      n   := intvalue(rec.num, x, y)
-      zero?(d := (rec.den) x) =>
-        zero? n => error "0/0 -- cannot compute value yet"
-        error "Function has a pole at the given point"
-      (n exquo d)::F
-
-    primitivePart f ==
-      cd := yCoordinates f
-      d  := gcd([content qelt(cd.num, i)
-                 for i in minIndex(cd.num) .. maxIndex(cd.num)]$List(F))
-                   * primitivePart(cd.den)
-      represents [qelt(cd.num, i) / d
-               for i in minIndex(cd.num) .. maxIndex(cd.num)]$Vector(RF)
-
-    reduceBasisAtInfinity b ==
-      x := monomial(1, 1)$UP ::RF
-      concat([[f for j in 0.. while
-                integralAtInfinity?(f := x**j * qelt(b, i))]$Vector($)
-                      for i in minIndex b .. maxIndex b]$List(Vector $))
-
-    complementaryBasis b ==
-      m := inverse(traceMatrix b)::Matrix(RF)
-      [represents row(m, i) for i in minRowIndex m .. maxRowIndex m]
-
-    integralAtInfinity? f ==
-      not any?(infOrder(#1) < 0,
-         coordinates(f) * inverseIntegralMatrixAtInfinity())$Vector(RF)
-
-    numberOfComponents() ==
-      count(integralAtInfinity?, integralBasis())$Vector($)
-
-    represents(v:Vector UP, d:UP) ==
-      represents
-        [qelt(v, i) / d for i in minIndex v .. maxIndex v]$Vector(RF)
-
-    genus() ==
-      ds := discriminant()
-      d  := degree(retract(ds)@UP) + infOrder(ds * determinant(
-             integralMatrixAtInfinity() * inverseIntegralMatrix()) ** 2)
-      dd := (((d exquo 2)::Z - rank()) exquo numberOfComponents())::Z
-      (dd + 1)::NonNegativeInteger
-
-    repOrder(m, i) ==
-      nostart:Boolean := true
-      ans:Z := 0
-      r := row(m, i)
-      for j in minIndex r .. maxIndex r | qelt(r, j) ^= 0 repeat
-        ans :=
-          nostart => (nostart := false; infOrder qelt(r, j))
-          min(ans, infOrder qelt(r,j))
-      nostart => error "Null row"
-      ans
-
-    infValue f ==
-      zero? f => 0
-      (n := infOrder f) > 0 => 0
-      zero? n =>
-        (leadingCoefficient numer f) / (leadingCoefficient denom f)
-      error "f not locally integral at infinity"
-
-    rfmonom n ==
-      n < 0 => inv(monomial(1, (-n)::NonNegativeInteger)$UP :: RF)
-      monomial(1, n::NonNegativeInteger)$UP :: RF
-
-    kmin(m, v) ==
-      nostart:Boolean := true
-      k:Z := 0
-      ii  := minRowIndex m - (i0  := minIndex v)
-      for i in minIndex v .. maxIndex v | qelt(v, i) ^= 0 repeat
-        nk := repOrder(m, i + ii)
-        if nostart then (nostart := false; k := nk; i0 := i)
-        else
-          if nk < k then (k := nk; i0 := i)
-      nostart => "failed"
-      [i0, k]
-
-    normalizeAtInfinity w ==
-      ans   := copy w
-      infm  := inverseIntegralMatrixAtInfinity()
-      mhat  := zero(rank(), rank())$Matrix(RF)
-      ii    := minIndex w - minRowIndex mhat
-      repeat
-        m := coordinates(ans) * infm
-        r := [rfmonom repOrder(m, i)
-                     for i in minRowIndex m .. maxRowIndex m]$Vector(RF)
-        for i in minRowIndex m .. maxRowIndex m repeat
-          for j in minColIndex m .. maxColIndex m repeat
-            qsetelt_!(mhat, i, j, qelt(r, i + ii) * qelt(m, i, j))
-        sol := first nullSpace transpose map(infValue,
-                mhat)$MatrixCategoryFunctions2(RF, Vector RF, Vector RF,
-                             Matrix RF, Q, Vector Q, Vector Q, Matrix Q)
-        (pr := kmin(m, sol)) case "failed" => return ans
-        qsetelt_!(ans, pr.pos,
-         +/[Q2RF(qelt(sol, i)) * rfmonom(repOrder(m, i - ii) - pr.km)
-                  * qelt(ans, i) for i in minIndex sol .. maxIndex sol])
-
-    integral?(f:$, p:UP) ==
-      (r:=retractIfCan(p)@Union(F,"failed")) case F => integral?(f,r::F)
-      (integralCoordinates(f).den exquo p) case "failed"
-
-    differentiate(f:$, d:UP -> UP) ==
-      differentiate(f, differentiate(#1, d)$RF)
-
-@
 \section{package MMAP MultipleMap}
+<<dot>>=
+"MMAP" [color=orange,style=filled];
+"MultipleMap(a:INTDOM,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:INTDOM,e:UPOLYC(d),f:UPOLYC(FRAC(e)))"
+    [color=orange,style=filled];
+"MMAP" -> "PACKAGE"
+"MultipleMap(a:INTDOM,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:INTDOM,e:UPOLYC(d),f:UPOLYC(FRAC(e)))"
+    -> "Package"
+@
 <<package MMAP MultipleMap>>=
 )abbrev package MMAP MultipleMap
 ++ Lifting a map through 2 levels of polynomials
@@ -453,6 +53,14 @@ MultipleMap(R1,UP1,UPUP1,R2,UP2,UPUP2): Exports == Implementation where
 
 @
 \section{package FFCAT2 FunctionFieldCategoryFunctions2}
+<<dot>>=
+"FFCAT2" [color=orange,style=filled];
+"FunctionFieldCategoryFunctions2(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:FFCAT(a,b,c),e:UFD,f:UPOLYC(e),g:UPOLYC(FRAC(f)),h:FFCAT(e,f,g))"
+    [color=orange,style=filled];
+"FFCAT2" -> "PACKAGE"
+"FunctionFieldCategoryFunctions2(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:FFCAT(a,b,c),e:UFD,f:UPOLYC(e),g:UPOLYC(FRAC(f)),h:FFCAT(e,f,g))"
+-> "Package"
+@
 <<package FFCAT2 FunctionFieldCategoryFunctions2>>=
 )abbrev package FFCAT2 FunctionFieldCategoryFunctions2
 ++ Lifts a map from rings to function fields over them
@@ -481,6 +89,13 @@ FunctionFieldCategoryFunctions2(R1, UP1, UPUP1, F1, R2, UP2, UPUP2, F2):
 
 @
 \section{package CHVAR ChangeOfVariable}
+<<dot>>=
+"CHVAR" [color=orange,style=filled];
+"ChangeOfVariable(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)))"
+    [color=orange,style=filled];
+"CHVAR" -> "PACKAGE"
+"ChangeOfVariable(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)))" -> "Package"
+@
 <<package CHVAR ChangeOfVariable>>=
 )abbrev package CHVAR ChangeOfVariable
 ++ Sends a point to infinity
@@ -612,6 +227,15 @@ ChangeOfVariable(F, UP, UPUP): Exports == Implementation where
 
 @
 \section{domain RADFF RadicalFunctionField}
+<<dot>>=
+"RADFF" -> "FFCAT"
+"RadicalFunctionField(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:FRAC(b))"
+   -> "FunctionFieldCategory(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)))"
+"RADFF" -> "SAE"
+"RadicalFunctionField(a:UFD,b:UPOLYC(a),c:UPOLYC(FRAC(b)),d:FRAC(b))"
+   -> 
+"SimpleAlgebraicExtension(a:FRAC(UPOLYC(UFD)),b:UPOLYC(FRAC(UPOLYC(UFD))))"
+@
 <<domain RADFF RadicalFunctionField>>=
 )abbrev domain RADFF RadicalFunctionField
 ++ Function field defined by y**n = f(x)
@@ -992,7 +616,6 @@ AlgebraicFunctionField(F, UP, UPUP, modulus): Exports == Impl where
 --   intaux  rderf  intrf  CURVE  curvepkg  divisor  pfo
 --   intalg  intaf  efstruc  rdeef  intef  irexpand  integrat
 
-<<category FFCAT FunctionFieldCategory>>
 <<package MMAP MultipleMap>>
 <<package FFCAT2 FunctionFieldCategoryFunctions2>>
 <<package CHVAR ChangeOfVariable>>
diff --git a/src/algebra/naalgc.spad.pamphlet b/src/algebra/naalgc.spad.pamphlet
deleted file mode 100644
index b48429c..0000000
--- a/src/algebra/naalgc.spad.pamphlet
+++ /dev/null
@@ -1,1260 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/algebra naalgc.spad}
-\author{Johannes Grabmeier, Robert Wisbauer}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\section{category MONAD Monad}
-<<category MONAD Monad>>=
-)abbrev category MONAD Monad
-++ Authors: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: *, **
-++ Related Constructors: SemiGroup, Monoid, MonadWithUnit
-++ Also See:
-++ AMS Classifications:
-++ Keywords: Monad,  binary operation
-++ Reference:
-++  N. Jacobson: Structure and Representations of Jordan Algebras
-++  AMS, Providence, 1968
-++ Description:
-++  Monad is the class of all multiplicative monads, i.e. sets
-++  with a binary operation.
-Monad(): Category == SetCategory with
-    --operations
-      "*": (%,%) -> %
-        ++ a*b is the product of \spad{a} and b in a set with
-        ++ a binary operation.
-      rightPower: (%,PositiveInteger) -> %
-        ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
-        ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
-        ++ \spad{rightPower(a,1) := a}.
-      leftPower: (%,PositiveInteger) -> %
-        ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
-        ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
-        ++ \spad{leftPower(a,1) := a}.
-      "**": (%,PositiveInteger) -> %
-        ++ a**n returns the \spad{n}-th power of \spad{a},
-        ++ defined by repeated squaring.
-    add
-      import RepeatedSquaring(%)
-      x:% ** n:PositiveInteger == expt(x,n)
-      rightPower(a,n) ==
---        one? n => a
-        (n = 1) => a
-        res := a
-        for i in 1..(n-1) repeat res := res * a
-        res
-      leftPower(a,n) ==
---        one? n => a
-        (n = 1) => a
-        res := a
-        for i in 1..(n-1) repeat res := a * res
-        res
-
-@
-\section{category MONADWU MonadWithUnit}
-<<category MONADWU MonadWithUnit>>=
-)abbrev category MONADWU MonadWithUnit
-++ Authors: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: *, **, 1
-++ Related Constructors: SemiGroup, Monoid, Monad
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ Keywords: Monad with unit, binary operation
-++ Reference:
-++  N. Jacobson: Structure and Representations of Jordan Algebras
-++  AMS, Providence, 1968
-++ Description:
-++  MonadWithUnit is the class of multiplicative monads with unit,
-++  i.e. sets with a binary operation and a unit element.
-++ Axioms
-++    leftIdentity("*":(%,%)->%,1)   \tab{30} 1*x=x
-++    rightIdentity("*":(%,%)->%,1)  \tab{30} x*1=x
-++ Common Additional Axioms
-++    unitsKnown---if "recip" says "failed", that PROVES input wasn't a unit
-MonadWithUnit(): Category == Monad with
-    --constants
-      1: constant ->  %
-        ++ 1 returns the unit element, denoted by 1.
-    --operations
-      one?: % -> Boolean
-        ++ one?(a) tests whether \spad{a} is the unit 1.
-      rightPower: (%,NonNegativeInteger) -> %
-        ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
-        ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
-        ++ \spad{rightPower(a,0) := 1}.
-      leftPower: (%,NonNegativeInteger) -> %
-        ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
-        ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
-        ++ \spad{leftPower(a,0) := 1}.
-      "**": (%,NonNegativeInteger) -> %
-        ++ \spad{a**n} returns the \spad{n}-th power of \spad{a},
-        ++ defined by repeated squaring.
-      recip: % -> Union(%,"failed")
-        ++ recip(a) returns an element, which is both a left and a right
-        ++ inverse of \spad{a},
-        ++ or \spad{"failed"} if such an element doesn't exist or cannot
-        ++ be determined (see unitsKnown).
-      leftRecip: % -> Union(%,"failed")
-        ++ leftRecip(a) returns an element, which is a left inverse of \spad{a},
-        ++ or \spad{"failed"} if such an element doesn't exist or cannot
-        ++ be determined (see unitsKnown).
-      rightRecip: % -> Union(%,"failed")
-        ++ rightRecip(a) returns an element, which is a right inverse of
-        ++ \spad{a}, or \spad{"failed"} if such an element doesn't exist
-        ++ or cannot be determined (see unitsKnown).
-    add
-      import RepeatedSquaring(%)
-      one? x == x = 1
-      x:% ** n:NonNegativeInteger ==
-         zero? n => 1
-         expt(x,n pretend PositiveInteger)
-      rightPower(a,n) ==
-        zero? n => 1
-        res := 1
-        for i in 1..n repeat res := res * a
-        res
-      leftPower(a,n) ==
-        zero? n => 1
-        res := 1
-        for i in 1..n repeat res := a * res
-        res
-
-@
-\section{category NARNG NonAssociativeRng}
-<<category NARNG NonAssociativeRng>>=
-)abbrev category NARNG NonAssociativeRng
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 03 July 1991
-++ Basic Operations: +, *, -, **
-++ Related Constructors: Rng, Ring, NonAssociativeRing
-++ Also See:
-++ AMS Classifications:
-++ Keywords: not associative ring
-++ Reference:
-++  R.D. Schafer: An Introduction to Nonassociative Algebras
-++  Academic Press, New York, 1966
-++ Description:
-++  NonAssociativeRng is a basic ring-type structure, not necessarily
-++  commutative or associative, and not necessarily with unit.
-++  Axioms
-++    x*(y+z) = x*y + x*z
-++    (x+y)*z = x*z + y*z
-++  Common Additional Axioms
-++    noZeroDivisors  ab = 0 => a=0 or b=0
-NonAssociativeRng(): Category == Join(AbelianGroup,Monad)  with
-    associator: (%,%,%) -> %
-      ++ associator(a,b,c) returns \spad{(a*b)*c-a*(b*c)}.
-    commutator: (%,%) -> %
-      ++ commutator(a,b) returns \spad{a*b-b*a}.
-    antiCommutator: (%,%) -> %
-      ++ antiCommutator(a,b) returns \spad{a*b+b*a}.
-  add
-    associator(x,y,z) == (x*y)*z - x*(y*z)
-    commutator(x,y) == x*y - y*x
-    antiCommutator(x,y) == x*y + y*x
-
-@
-\section{category NASRING NonAssociativeRing}
-<<category NASRING NonAssociativeRing>>=
-)abbrev category NASRING NonAssociativeRing
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: +, *, -, **
-++ Related Constructors: NonAssociativeRng, Rng, Ring
-++ Also See:
-++ AMS Classifications:
-++ Keywords: non-associative ring with unit
-++ Reference:
-++  R.D. Schafer: An Introduction to Nonassociative Algebras
-++  Academic Press, New York, 1966
-++ Description:
-++  A NonAssociativeRing is a non associative rng which has a unit,
-++  the multiplication is not necessarily commutative or associative.
-NonAssociativeRing(): Category == Join(NonAssociativeRng,MonadWithUnit) with
-    --operations
-      characteristic: -> NonNegativeInteger
-        ++ characteristic() returns the characteristic of the ring.
-        --we can not make this a constant, since some domains are mutable
-      coerce: Integer -> %
-        ++ coerce(n) coerces the integer n to an element of the ring.
-   add
-      n:Integer
-      coerce(n) == n * 1$%
-
-@
-\section{category NAALG NonAssociativeAlgebra}
-<<category NAALG NonAssociativeAlgebra>>=
-)abbrev category NAALG NonAssociativeAlgebra
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: +, -, *, **
-++ Related Constructors: Algebra
-++ Also See:
-++ AMS Classifications:
-++ Keywords: nonassociative algebra
-++ Reference:
-++  R.D. Schafer: An Introduction to Nonassociative Algebras
-++  Academic Press, New York, 1966
-++ Description:
-++   NonAssociativeAlgebra is the category of non associative algebras
-++   (modules which are themselves non associative rngs).
-++   Axioms
-++      r*(a*b) = (r*a)*b = a*(r*b)
-NonAssociativeAlgebra(R:CommutativeRing): Category == _
-  Join(NonAssociativeRng, Module R) with
-    --operations
-    plenaryPower : (%,PositiveInteger) -> %
-      ++ plenaryPower(a,n) is recursively defined to be
-      ++ \spad{plenaryPower(a,n-1)*plenaryPower(a,n-1)} for \spad{n>1}
-      ++ and \spad{a} for \spad{n=1}.
-  add
-    plenaryPower(a,n) ==
---      one? n => a
-      ( n = 1 ) => a
-      n1 : PositiveInteger := (n-1)::NonNegativeInteger::PositiveInteger
-      plenaryPower(a,n1) * plenaryPower(a,n1)
-
-@
-\section{category FINAALG FiniteRankNonAssociativeAlgebra}
-<<category FINAALG FiniteRankNonAssociativeAlgebra>>=
-)abbrev category FINAALG FiniteRankNonAssociativeAlgebra
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 12 June 1991
-++ Basic Operations: +,-,*,**, someBasis
-++ Related Constructors: FramedNonAssociativeAlgebra, FramedAlgebra,
-++   FiniteRankAssociativeAlgebra
-++ Also See:
-++ AMS Classifications:
-++ Keywords: nonassociative algebra, basis
-++ References:
-++   R.D. Schafer: An Introduction to Nonassociative Algebras
-++   Academic Press, New York, 1966
-++
-++   R. Wisbauer: Bimodule Structure of Algebra
-++   Lecture Notes Univ. Duesseldorf 1991
-++ Description:
-++   A FiniteRankNonAssociativeAlgebra is a non associative algebra over
-++   a commutative ring R which is a free \spad{R}-module of finite rank.
-FiniteRankNonAssociativeAlgebra(R:CommutativeRing):
- Category == NonAssociativeAlgebra R with
-    someBasis : () -> Vector %
-      ++ someBasis() returns some \spad{R}-module basis.
-    rank : () -> PositiveInteger
-      ++ rank() returns the rank of the algebra as \spad{R}-module.
-    conditionsForIdempotents: Vector % -> List Polynomial R
-      ++ conditionsForIdempotents([v1,...,vn]) determines a complete list
-      ++ of polynomial equations for the coefficients of idempotents
-      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
-    structuralConstants: Vector % -> Vector Matrix R
-      ++ structuralConstants([v1,v2,...,vm]) calculates the structural
-      ++ constants \spad{[(gammaijk) for k in 1..m]} defined by
-      ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijm * vm},
-      ++ where \spad{[v1,...,vm]} is an \spad{R}-module basis
-      ++ of a subalgebra.
-    leftRegularRepresentation: (% , Vector %) -> Matrix R
-      ++ leftRegularRepresentation(a,[v1,...,vn]) returns the matrix of
-      ++ the linear map defined by left multiplication by \spad{a}
-      ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
-    rightRegularRepresentation: (% , Vector %) -> Matrix R
-      ++ rightRegularRepresentation(a,[v1,...,vn]) returns the matrix of
-      ++ the linear map defined by right multiplication by \spad{a}
-      ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
-    leftTrace: %  -> R
-      ++ leftTrace(a) returns the trace of the left regular representation
-      ++ of \spad{a}.
-    rightTrace: %  -> R
-      ++ rightTrace(a) returns the trace of the right regular representation
-      ++ of \spad{a}.
-    leftNorm: %  -> R
-      ++ leftNorm(a) returns the determinant of the left regular representation
-      ++ of \spad{a}.
-    rightNorm: %  -> R
-      ++ rightNorm(a) returns the determinant of the right regular
-      ++ representation of \spad{a}.
-    coordinates: (%, Vector %) -> Vector R
-      ++ coordinates(a,[v1,...,vn]) returns the coordinates of \spad{a}
-      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
-    coordinates: (Vector %, Vector %) -> Matrix R
-      ++ coordinates([a1,...,am],[v1,...,vn]) returns a matrix whose
-      ++ i-th row is formed by the coordinates of \spad{ai}
-      ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
-    represents: (Vector R, Vector %) -> %
-      ++ represents([a1,...,am],[v1,...,vm]) returns the linear
-      ++ combination \spad{a1*vm + ... + an*vm}.
-    leftDiscriminant: Vector % -> R
-      ++ leftDiscriminant([v1,...,vn]) returns  the determinant of the
-      ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
-      ++ and \spad{j}-th column is given by the left trace of the product
-      ++ \spad{vi*vj}.
-      ++ Note: the same as \spad{determinant(leftTraceMatrix([v1,...,vn]))}.
-    rightDiscriminant: Vector % -> R
-      ++ rightDiscriminant([v1,...,vn]) returns  the determinant of the
-      ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
-      ++ and \spad{j}-th column is given by the right trace of the product
-      ++ \spad{vi*vj}.
-      ++ Note: the same as \spad{determinant(rightTraceMatrix([v1,...,vn]))}.
-    leftTraceMatrix: Vector % -> Matrix R
-      ++ leftTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
-      ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
-      ++ by the left trace of the product \spad{vi*vj}.
-    rightTraceMatrix: Vector % -> Matrix R
-      ++ rightTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
-      ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
-      ++ by the right trace of the product \spad{vi*vj}.
-    leftCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
-      ++ leftCharacteristicPolynomial(a) returns the characteristic
-      ++ polynomial of the left regular representation of \spad{a}
-      ++ with respect to any basis.
-    rightCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
-      ++ rightCharacteristicPolynomial(a) returns the characteristic
-      ++ polynomial of the right regular representation of \spad{a}
-      ++ with respect to any basis.
-
-    --we not necessarily have a unit
-    --if R has CharacteristicZero then CharacteristicZero
-    --if R has CharacteristicNonZero then CharacteristicNonZero
-
-    commutative?:()-> Boolean
-      ++ commutative?() tests if multiplication in the algebra
-      ++ is commutative.
-    antiCommutative?:()-> Boolean
-      ++ antiCommutative?() tests if \spad{a*a = 0}
-      ++ for all \spad{a} in the algebra.
-      ++ Note: this implies \spad{a*b + b*a = 0} for all \spad{a} and \spad{b}.
-    associative?:()-> Boolean
-      ++ associative?() tests if multiplication in algebra
-      ++ is associative.
-    antiAssociative?:()-> Boolean
-      ++ antiAssociative?() tests if multiplication in algebra
-      ++ is anti-associative, i.e. \spad{(a*b)*c + a*(b*c) = 0}
-      ++ for all \spad{a},b,c in the algebra.
-    leftAlternative?: ()-> Boolean
-      ++ leftAlternative?() tests if \spad{2*associator(a,a,b) = 0}
-      ++ for all \spad{a}, b in the algebra.
-      ++ Note: we only can test this; in general we don't know
-      ++ whether \spad{2*a=0} implies \spad{a=0}.
-    rightAlternative?: ()-> Boolean
-      ++ rightAlternative?() tests if \spad{2*associator(a,b,b) = 0}
-      ++ for all \spad{a}, b in the algebra.
-      ++ Note: we only can test this; in general we don't know
-      ++ whether \spad{2*a=0} implies \spad{a=0}.
-    flexible?: ()->  Boolean
-      ++ flexible?() tests if \spad{2*associator(a,b,a) = 0}
-      ++ for all \spad{a}, b in the algebra.
-      ++ Note: we only can test this; in general we don't know
-      ++ whether \spad{2*a=0} implies \spad{a=0}.
-    alternative?: ()-> Boolean
-      ++ alternative?() tests if
-      ++ \spad{2*associator(a,a,b) = 0 = 2*associator(a,b,b)}
-      ++ for all \spad{a}, b in the algebra.
-      ++ Note: we only can test this; in general we don't know
-      ++ whether \spad{2*a=0} implies \spad{a=0}.
-    powerAssociative?:()-> Boolean
-      ++ powerAssociative?() tests if all subalgebras
-      ++ generated by a single element are associative.
-    jacobiIdentity?:() -> Boolean
-      ++ jacobiIdentity?() tests if \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
-      ++ for all \spad{a},b,c in the algebra. For example, this holds
-      ++ for crossed products of 3-dimensional vectors.
-    lieAdmissible?: () -> Boolean
-      ++ lieAdmissible?() tests if the algebra defined by the commutators
-      ++ is a Lie algebra, i.e. satisfies the Jacobi identity.
-      ++ The property of anticommutativity follows from definition.
-    jordanAdmissible?: () -> Boolean
-      ++ jordanAdmissible?() tests if 2 is invertible in the
-      ++ coefficient domain and the multiplication defined by
-      ++ \spad{(1/2)(a*b+b*a)} determines a
-      ++ Jordan algebra, i.e. satisfies the Jordan identity.
-      ++ The property of \spadatt{commutative("*")}
-      ++ follows from by definition.
-    noncommutativeJordanAlgebra?: () -> Boolean
-      ++ noncommutativeJordanAlgebra?() tests if the algebra
-      ++ is flexible and Jordan admissible.
-    jordanAlgebra?:() -> Boolean
-      ++ jordanAlgebra?() tests if the algebra is commutative,
-      ++ characteristic is not 2, and \spad{(a*b)*a**2 - a*(b*a**2) = 0}
-      ++ for all \spad{a},b,c in the algebra (Jordan identity).
-      ++ Example:
-      ++ for every associative algebra \spad{(A,+,@)} we can construct a
-      ++ Jordan algebra \spad{(A,+,*)}, where \spad{a*b := (a@b+b@a)/2}.
-    lieAlgebra?:() -> Boolean
-      ++ lieAlgebra?() tests if the algebra is anticommutative
-      ++ and \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
-      ++ for all \spad{a},b,c in the algebra (Jacobi identity).
-      ++ Example:
-      ++ for every associative algebra \spad{(A,+,@)} we can construct a
-      ++ Lie algebra \spad{(A,+,*)}, where \spad{a*b := a@b-b@a}.
-
-    if R has IntegralDomain then
-      -- we not neccessarily have a unit, hence we don't inherit
-      -- the next 3 functions anc hence copy them from MonadWithUnit:
-      recip: % -> Union(%,"failed")
-        ++ recip(a) returns an element, which is both a left and a right
-        ++ inverse of \spad{a},
-        ++ or \spad{"failed"} if there is no unit element, if such an
-        ++ element doesn't exist or cannot be determined (see unitsKnown).
-      leftRecip: % -> Union(%,"failed")
-        ++ leftRecip(a) returns an element, which is a left inverse of \spad{a},
-        ++ or \spad{"failed"} if there is no unit element, if such an
-        ++ element doesn't exist or cannot be determined (see unitsKnown).
-      rightRecip: % -> Union(%,"failed")
-        ++ rightRecip(a) returns an element, which is a right inverse of
-        ++ \spad{a},
-        ++ or \spad{"failed"} if there is no unit element, if such an
-        ++ element doesn't exist or cannot be determined (see unitsKnown).
-      associatorDependence:() -> List Vector R
-        ++ associatorDependence() looks for the associator identities, i.e.
-        ++ finds a basis of the solutions of the linear combinations of the
-        ++ six permutations of \spad{associator(a,b,c)} which yield 0,
-        ++ for all \spad{a},b,c in the algebra.
-        ++ The order of the permutations is \spad{123 231 312 132 321 213}.
-      leftMinimalPolynomial : % -> SparseUnivariatePolynomial R
-        ++ leftMinimalPolynomial(a) returns the polynomial determined by the
-        ++ smallest non-trivial linear combination of left powers of \spad{a}.
-        ++ Note: the polynomial never has a constant term as in general
-        ++ the algebra has no unit.
-      rightMinimalPolynomial : % -> SparseUnivariatePolynomial R
-        ++ rightMinimalPolynomial(a) returns the polynomial determined by the
-        ++ smallest non-trivial linear
-        ++ combination of right powers of \spad{a}.
-        ++ Note: the polynomial never has a constant term as in general
-        ++ the algebra has no unit.
-      leftUnits:() -> Union(Record(particular: %, basis: List %), "failed")
-        ++ leftUnits() returns the affine space of all left units of the
-        ++ algebra, or \spad{"failed"} if there is none.
-      rightUnits:() -> Union(Record(particular: %, basis: List %), "failed")
-        ++ rightUnits() returns the affine space of all right units of the
-        ++ algebra, or \spad{"failed"} if there is none.
-      leftUnit:() -> Union(%, "failed")
-        ++ leftUnit() returns a left unit of the algebra
-        ++ (not necessarily unique), or \spad{"failed"} if there is none.
-      rightUnit:() -> Union(%, "failed")
-        ++ rightUnit() returns a right unit of the algebra
-        ++ (not necessarily unique), or \spad{"failed"} if there is none.
-      unit:() -> Union(%, "failed")
-        ++ unit() returns a unit of the algebra (necessarily unique),
-        ++ or \spad{"failed"} if there is none.
-      -- we not necessarily have a unit, hence we can't say anything
-      -- about characteristic
-      -- if R has CharacteristicZero then CharacteristicZero
-      -- if R has CharacteristicNonZero then CharacteristicNonZero
-      unitsKnown
-        ++ unitsKnown means that \spadfun{recip} truly yields reciprocal
-        ++ or \spad{"failed"} if not a unit,
-        ++ similarly for \spadfun{leftRecip} and
-        ++ \spadfun{rightRecip}. The reason is that we use left, respectively
-        ++ right, minimal polynomials to decide this question.
-
-  add
-    --n := rank()
-    --b := someBasis()
-    --gamma : Vector Matrix R := structuralConstants b
-    -- here is a problem: there seems to be a problem having local
-    -- variables in the capsule of a category, furthermore
-    -- see the commented code of conditionsForIdempotents, where
-    -- we call structuralConstants, which also doesn't work
-    -- at runtime, i.e. is not properly inherited, hence for
-    -- the moment we put the code for
-    -- conditionsForIdempotents, structuralConstants, unit, leftUnit,
-    -- rightUnit into the domain constructor ALGSC
-    V  ==> Vector
-    M  ==> Matrix
-    REC  ==> Record(particular: Union(V R,"failed"),basis: List V R)
-    LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
-
-
-    SUP ==>  SparseUnivariatePolynomial
-    NNI ==>  NonNegativeInteger
-    -- next 2 functions: use a general characteristicPolynomial
-    leftCharacteristicPolynomial a ==
-       n := rank()$%
-       ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
-       mb : Matrix SUP R := zero(n,n)
-       for i in 1..n repeat
-         for j in 1..n repeat
-           mb(i,j):=
-             i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
-             monomial(ma(i,j),1)$SUP(R)
-       determinant mb
-
-    rightCharacteristicPolynomial a ==
-       n := rank()$%
-       ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
-       mb : Matrix SUP R := zero(n,n)
-       for i in 1..n repeat
-         for j in 1..n repeat
-           mb(i,j):=
-             i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
-             monomial(ma(i,j),1)$SUP(R)
-       determinant mb
-
-
-
-    leftTrace a ==
-      t : R := 0
-      ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
-      for i in 1..rank()$% repeat
-        t := t + elt(ma,i,i)
-      t
-
-    rightTrace a ==
-      t : R := 0
-      ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
-      for i in 1..rank()$% repeat
-        t := t + elt(ma,i,i)
-      t
-
-    leftNorm a == determinant leftRegularRepresentation(a,someBasis()$%)
-
-    rightNorm a == determinant rightRegularRepresentation(a,someBasis()$%)
-
-
-    antiAssociative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-        for j in 1..n repeat
-          for k in 1..n repeat
-            not zero? ( (b.i*b.j)*b.k + b.i*(b.j*b.k) )  =>
-              messagePrint("algebra is not anti-associative")$OutputForm
-              return false
-      messagePrint("algebra is anti-associative")$OutputForm
-      true
-
-
-    jordanAdmissible?() ==
-      b := someBasis()
-      n := rank()
-      recip(2 * 1$R) case "failed" =>
-        messagePrint("this algebra is not Jordan admissible, as 2 is not invertible in the ground ring")$OutputForm
-        false
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         for l in 1..n repeat
-           not zero? ( _
-             antiCommutator(antiCommutator(b.i,b.j),antiCommutator(b.l,b.k)) + _
-             antiCommutator(antiCommutator(b.l,b.j),antiCommutator(b.k,b.i)) + _
-             antiCommutator(antiCommutator(b.k,b.j),antiCommutator(b.i,b.l))   _
-                      ) =>
-               messagePrint("this algebra is not Jordan admissible")$OutputForm
-               return false
-      messagePrint("this algebra is Jordan admissible")$OutputForm
-      true
-
-    lieAdmissible?() ==
-      n := rank()
-      b := someBasis()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-          not zero? (commutator(commutator(b.i,b.j),b.k) _
-                  + commutator(commutator(b.j,b.k),b.i) _
-                  + commutator(commutator(b.k,b.i),b.j))   =>
-            messagePrint("this algebra is not Lie admissible")$OutputForm
-            return false
-      messagePrint("this algebra is Lie admissible")$OutputForm
-      true
-
-    -- conditionsForIdempotents b  ==
-    --   n := rank()
-    --   gamma : Vector Matrix R := structuralConstants b
-    --   listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
-    --   symbolsForCoef : Vector Symbol :=
-    --     [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
-    --   conditions : List Polynomial R := []
-    --  for k in 1..n repeat
-    --    xk := symbolsForCoef.k
-    --    p : Polynomial R :=  monomial( - 1$Polynomial(R), [xk], [1] )
-    --    for i in 1..n repeat
-    --      for j in 1..n repeat
-    --        xi := symbolsForCoef.i
-    --        xj := symbolsForCoef.j
-    --        p := p + monomial(_
-    --          elt((gamma.k),i,j) :: Polynomial(R), [xi,xj], [1,1])
-    --    conditions := cons(p,conditions)
-    --  conditions
-
-    structuralConstants b ==
-      --n := rank()
-      -- be careful with the possibility that b is not a basis
-      m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
-      sC : Vector Matrix R := [new(m,m,0$R) for k in 1..m]
-      for i in 1..m repeat
-        for j in 1..m repeat
-          covec : Vector R := coordinates(b.i * b.j, b)
-          for k in 1..m repeat
-             setelt( sC.k, i, j, covec.k )
-      sC
-
-    if R has IntegralDomain then
-
-      leftRecip x ==
-        zero? x => "failed"
-        lu := leftUnit()
-        lu case "failed" => "failed"
-        b := someBasis()
-        xx : % := (lu :: %)
-        k  : PositiveInteger := 1
-        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
-        listOfPowers : List % := [xx]
-        while rank(cond) = k repeat
-          k := k+1
-          xx := xx*x
-          listOfPowers := cons(xx,listOfPowers)
-          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
-        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
-        invC := recip vectorOfCoef.1
-        invC case "failed" => "failed"
-        invCR : R :=  - (invC :: R)
-        reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
-         2..maxIndex vectorOfCoef for power in reverse listOfPowers])
-
-
-      rightRecip x ==
-        zero? x => "failed"
-        ru := rightUnit()
-        ru case "failed" => "failed"
-        b := someBasis()
-        xx : % := (ru :: %)
-        k  : PositiveInteger := 1
-        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
-        listOfPowers : List % := [xx]
-        while rank(cond) = k repeat
-          k := k+1
-          xx := x*xx
-          listOfPowers := cons(xx,listOfPowers)
-          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
-        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
-        invC := recip vectorOfCoef.1
-        invC case "failed" => "failed"
-        invCR : R :=  - (invC :: R)
-        reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
-         2..maxIndex vectorOfCoef for power in reverse listOfPowers])
-
-
-      recip x ==
-        lrx := leftRecip x
-        lrx case "failed" => "failed"
-        rrx := rightRecip x
-        rrx case "failed" => "failed"
-        (lrx :: %) ^= (rrx :: %)  => "failed"
-        lrx :: %
-
-
-      leftMinimalPolynomial x ==
-        zero? x =>  monomial(1$R,1)$(SparseUnivariatePolynomial R)
-        b := someBasis()
-        xx : % := x
-        k  : PositiveInteger := 1
-        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
-        while rank(cond) = k repeat
-          k := k+1
-          xx := x*xx
-          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
-        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
-        res : SparseUnivariatePolynomial R := 0
-        for i in 1..k repeat
-          res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
-        res
-
-      rightMinimalPolynomial x ==
-        zero? x =>  monomial(1$R,1)$(SparseUnivariatePolynomial R)
-        b := someBasis()
-        xx : % := x
-        k  : PositiveInteger := 1
-        cond : Matrix R := coordinates(xx,b) :: Matrix(R)
-        while rank(cond) = k repeat
-          k := k+1
-          xx := xx*x
-          cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
-        vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
-        res : SparseUnivariatePolynomial R := 0
-        for i in 1..k repeat
-          res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
-        res
-
-
-
-      associatorDependence() ==
-        n := rank()
-        b := someBasis()
-        cond : Matrix(R) := new(n**4,6,0$R)$Matrix(R)
-        z : Integer := 0
-        for i in 1..n repeat
-         for j in 1..n repeat
-          for k in 1..n repeat
-           a123 : Vector R := coordinates(associator(b.i,b.j,b.k),b)
-           a231 : Vector R := coordinates(associator(b.j,b.k,b.i),b)
-           a312 : Vector R := coordinates(associator(b.k,b.i,b.j),b)
-           a132 : Vector R := coordinates(associator(b.i,b.k,b.j),b)
-           a321 : Vector R := coordinates(associator(b.k,b.j,b.i),b)
-           a213 : Vector R := coordinates(associator(b.j,b.i,b.k),b)
-           for r in 1..n repeat
-            z:= z+1
-            setelt(cond,z,1,elt(a123,r))
-            setelt(cond,z,2,elt(a231,r))
-            setelt(cond,z,3,elt(a312,r))
-            setelt(cond,z,4,elt(a132,r))
-            setelt(cond,z,5,elt(a321,r))
-            setelt(cond,z,6,elt(a213,r))
-        nullSpace(cond)
-
-    jacobiIdentity?()  ==
-      n := rank()
-      b := someBasis()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-          not zero? ((b.i*b.j)*b.k + (b.j*b.k)*b.i + (b.k*b.i)*b.j) =>
-            messagePrint("Jacobi identity does not hold")$OutputForm
-            return false
-      messagePrint("Jacobi identity holds")$OutputForm
-      true
-
-    lieAlgebra?()  ==
-      not antiCommutative?() =>
-        messagePrint("this is not a Lie algebra")$OutputForm
-        false
-      not jacobiIdentity?() =>
-        messagePrint("this is not a Lie algebra")$OutputForm
-        false
-      messagePrint("this is a Lie algebra")$OutputForm
-      true
-
-
-
-
-    jordanAlgebra?()  ==
-      b := someBasis()
-      n := rank()
-      recip(2 * 1$R) case "failed" =>
-        messagePrint("this is not a Jordan algebra, as 2 is not invertible in the ground ring")$OutputForm
-        false
-      not commutative?() =>
-        messagePrint("this is not a Jordan algebra")$OutputForm
-        false
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         for l in 1..n repeat
-           not zero? (associator(b.i,b.j,b.l*b.k)+_
-               associator(b.l,b.j,b.k*b.i)+associator(b.k,b.j,b.i*b.l)) =>
-             messagePrint("not a Jordan algebra")$OutputForm
-             return false
-      messagePrint("this is a Jordan algebra")$OutputForm
-      true
-
-    noncommutativeJordanAlgebra?() ==
-      b := someBasis()
-      n := rank()
-      recip(2 * 1$R) case "failed" =>
-        messagePrint("this is not a noncommutative Jordan algebra, as 2 is not invertible in the ground ring")$OutputForm
-        false
-      not flexible?()$% =>
-        messagePrint("this is not a noncommutative Jordan algebra, as it is not flexible")$OutputForm
-        false
-      not jordanAdmissible?()$% =>
-        messagePrint("this is not a noncommutative Jordan algebra, as it is not Jordan admissible")$OutputForm
-        false
-      messagePrint("this is a noncommutative Jordan algebra")$OutputForm
-      true
-
-    antiCommutative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-        for j in i..n repeat
-          not zero? (i=j => b.i*b.i; b.i*b.j + b.j*b.i) =>
-            messagePrint("algebra is not anti-commutative")$OutputForm
-            return false
-      messagePrint("algebra is anti-commutative")$OutputForm
-      true
-
-    commutative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in i+1..n repeat
-         not zero? commutator(b.i,b.j) =>
-           messagePrint("algebra is not commutative")$OutputForm
-           return false
-      messagePrint("algebra is commutative")$OutputForm
-      true
-
-
-    associative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         not zero? associator(b.i,b.j,b.k) =>
-           messagePrint("algebra is not associative")$OutputForm
-           return false
-      messagePrint("algebra is associative")$OutputForm
-      true
-
-    leftAlternative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
-           messagePrint("algebra is not left alternative")$OutputForm
-           return false
-      messagePrint("algebra satisfies 2*associator(a,a,b) = 0")$OutputForm
-      true
-
-    rightAlternative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
-           messagePrint("algebra is not right alternative")$OutputForm
-           return false
-      messagePrint("algebra satisfies 2*associator(a,b,b) = 0")$OutputForm
-      true
-
-    flexible?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         not zero? (associator(b.i,b.j,b.k) + associator(b.k,b.j,b.i)) =>
-           messagePrint("algebra is not flexible")$OutputForm
-           return false
-      messagePrint("algebra satisfies 2*associator(a,b,a) = 0")$OutputForm
-      true
-
-    alternative?() ==
-      b := someBasis()
-      n := rank()
-      for i in 1..n repeat
-       for j in 1..n repeat
-        for k in 1..n repeat
-         not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
-           messagePrint("algebra is not alternative")$OutputForm
-           return false
-         not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
-           messagePrint("algebra is not alternative")$OutputForm
-           return false
-      messagePrint("algebra satisfies 2*associator(a,b,b) = 0 =  2*associator(a,a,b) = 0")$OutputForm
-      true
-
-    leftDiscriminant v == determinant leftTraceMatrix v
-    rightDiscriminant v == determinant rightTraceMatrix v
-
-    coordinates(v:Vector %, b:Vector %) ==
-      m := new(#v, #b, 0)$Matrix(R)
-      for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
-        setRow_!(m, j, coordinates(qelt(v, i), b))
-      m
-
-    represents(v, b) ==
-      m := minIndex v - 1
-      reduce(_+,[v(i+m) * b(i+m) for i in 1..maxIndex b])
-
-    leftTraceMatrix v ==
-      matrix [[leftTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
-               for i in minIndex v .. maxIndex v]$List(List R)
-
-    rightTraceMatrix v ==
-      matrix [[rightTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
-               for i in minIndex v .. maxIndex v]$List(List R)
-
-    leftRegularRepresentation(x, b) ==
-      m := minIndex b - 1
-      matrix
-       [parts coordinates(x*b(i+m),b) for i in 1..rank()]$List(List R)
-
-    rightRegularRepresentation(x, b) ==
-      m := minIndex b - 1
-      matrix
-       [parts coordinates(b(i+m)*x,b) for i in 1..rank()]$List(List R)
-
-@
-\section{category FRNAALG FramedNonAssociativeAlgebra}
-<<category FRNAALG FramedNonAssociativeAlgebra>>=
-)abbrev category FRNAALG FramedNonAssociativeAlgebra
-++ Author: J. Grabmeier, R. Wisbauer
-++ Date Created: 01 March 1991
-++ Date Last Updated: 11 June 1991
-++ Basic Operations: +,-,*,**,basis
-++ Related Constructors: FiniteRankNonAssociativeAlgebra, FramedAlgebra,
-++   FiniteRankAssociativeAlgebra
-++ Also See:
-++ AMS Classifications:
-++ Keywords: nonassociative algebra, basis
-++ Reference:
-++  R.D. Schafer: An Introduction to Nonassociative Algebras
-++  Academic Press, New York, 1966
-++ Description:
-++   FramedNonAssociativeAlgebra(R) is a
-++   \spadtype{FiniteRankNonAssociativeAlgebra} (i.e. a non associative
-++   algebra over R which is a free \spad{R}-module of finite rank)
-++   over a commutative ring R together with a fixed \spad{R}-module basis.
-FramedNonAssociativeAlgebra(R:CommutativeRing):
-        Category == FiniteRankNonAssociativeAlgebra(R) with
-  --operations
-    basis: () -> Vector %
-      ++ basis() returns the fixed \spad{R}-module basis.
-    coordinates: % -> Vector R
-      ++ coordinates(a) returns the coordinates of \spad{a}
-      ++ with respect to the
-      ++ fixed \spad{R}-module basis.
-    coordinates: Vector % -> Matrix R
-      ++ coordinates([a1,...,am]) returns a matrix whose i-th row
-      ++ is formed by the coordinates of \spad{ai} with respect to the
-      ++ fixed \spad{R}-module basis.
-    elt : (%,Integer) -> R
-      ++ elt(a,i) returns the i-th coefficient of \spad{a} with respect to the
-      ++ fixed \spad{R}-module basis.
-    structuralConstants:() -> Vector Matrix R
-      ++ structuralConstants() calculates the structural constants
-      ++ \spad{[(gammaijk) for k in 1..rank()]} defined by
-      ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijn * vn},
-      ++ where \spad{v1},...,\spad{vn} is the fixed \spad{R}-module basis.
-    conditionsForIdempotents: () -> List Polynomial R
-      ++ conditionsForIdempotents() determines a complete list
-      ++ of polynomial equations for the coefficients of idempotents
-      ++ with respect to the fixed \spad{R}-module basis.
-    represents: Vector R -> %
-      ++ represents([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
-      ++ where \spad{v1}, ..., \spad{vn} are the elements of the
-      ++ fixed \spad{R}-module basis.
-    convert: % -> Vector R
-      ++ convert(a) returns the coordinates of \spad{a} with respect to the
-      ++ fixed \spad{R}-module basis.
-    convert: Vector R -> %
-      ++ convert([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
-      ++ where \spad{v1}, ..., \spad{vn} are the elements of the
-      ++ fixed \spad{R}-module basis.
-    leftDiscriminant : () -> R
-      ++ leftDiscriminant() returns the
-      ++ determinant of the \spad{n}-by-\spad{n}
-      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
-      ++ given by the left trace of the product \spad{vi*vj}, where
-      ++ \spad{v1},...,\spad{vn} are the
-      ++ elements of the fixed \spad{R}-module basis.
-      ++ Note: the same as \spad{determinant(leftTraceMatrix())}.
-    rightDiscriminant : () -> R
-      ++ rightDiscriminant() returns the determinant of the \spad{n}-by-\spad{n}
-      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
-      ++ given by the right trace of the product \spad{vi*vj}, where
-      ++ \spad{v1},...,\spad{vn} are the elements of
-      ++ the fixed \spad{R}-module basis.
-      ++ Note: the same as \spad{determinant(rightTraceMatrix())}.
-    leftTraceMatrix : () -> Matrix R
-      ++ leftTraceMatrix() is the \spad{n}-by-\spad{n}
-      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
-      ++ given by left trace of the product \spad{vi*vj},
-      ++ where \spad{v1},...,\spad{vn} are the
-      ++ elements of the fixed \spad{R}-module
-      ++ basis.
-    rightTraceMatrix : () -> Matrix R
-      ++ rightTraceMatrix() is the \spad{n}-by-\spad{n}
-      ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
-      ++ given by the right trace of the product \spad{vi*vj}, where
-      ++ \spad{v1},...,\spad{vn} are the elements
-      ++ of the fixed \spad{R}-module basis.
-    leftRegularRepresentation : % -> Matrix R
-      ++ leftRegularRepresentation(a) returns the matrix of the linear
-      ++ map defined by left multiplication by \spad{a} with respect
-      ++ to the fixed \spad{R}-module basis.
-    rightRegularRepresentation : % -> Matrix R
-      ++ rightRegularRepresentation(a) returns the matrix of the linear
-      ++ map defined by right multiplication by \spad{a} with respect
-      ++ to the fixed \spad{R}-module basis.
-    if R has Field then
-      leftRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
-        ++ leftRankPolynomial() calculates the left minimal polynomial
-        ++ of the generic element in the algebra,
-        ++ defined by the same structural
-        ++ constants over the polynomial ring in symbolic coefficients with
-        ++ respect to the fixed basis.
-      rightRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
-        ++ rightRankPolynomial() calculates the right minimal polynomial
-        ++ of the generic element in the algebra,
-        ++ defined by the same structural
-        ++ constants over the polynomial ring in symbolic coefficients with
-        ++ respect to the fixed basis.
-    apply: (Matrix R, %) -> %
-      ++ apply(m,a) defines a left operation of n by n matrices
-      ++ where n is the rank of the algebra in terms of matrix-vector
-      ++ multiplication, this is a substitute for a left module structure.
-      ++ Error: if shape of matrix doesn't fit.
-    --attributes
-    --attributes
-      --separable <=> discriminant() ^= 0
-  add
-
-    V  ==> Vector
-    M  ==> Matrix
-    P  ==> Polynomial
-    F  ==> Fraction
-    REC  ==> Record(particular: Union(V R,"failed"),basis: List V R)
-    LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
-    CVMP ==> CoerceVectorMatrixPackage(R)
-
-    --GA ==> GenericNonAssociativeAlgebra(R,rank()$%,_
-    -- [random()$Character :: String :: Symbol for i in 1..rank()$%], _
-    -- structuralConstants()$%)
-    --y : GA := generic()
-    if R has Field then
-      leftRankPolynomial() ==
-        n := rank()
-        b := basis()
-        gamma : Vector Matrix R := structuralConstants b
-        listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
-        symbolsForCoef : Vector Symbol :=
-          [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
-        xx : M P R
-        mo : P R
-        x : M P R := new(1,n,0)
-        for i in 1..n repeat
-          mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
-          qsetelt_!(x,1,i,mo)
-        y : M P R := copy x
-        k  : PositiveInteger := 1
-        cond : M P R := copy x
-        -- multiplication in the generic algebra means using
-        -- the structural matrices as bilinear forms.
-        -- left multiplication by x, we prepare for that:
-        genGamma : V M P R :=  coerceP$CVMP gamma
-        x := reduce(horizConcat,[x*genGamma(i) for i in 1..#genGamma])
-        while rank(cond) = k repeat
-          k := k+1
-          for i in 1..n repeat
-            setelt(xx,[1],[i],x*transpose y)
-          y := copy xx
-          cond := horizConcat(cond, xx)
-        vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
-        res : SparseUnivariatePolynomial P R := 0
-        for i in 1..k repeat
-         res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial  P R)
-        res
-
-      rightRankPolynomial() ==
-        n := rank()
-        b := basis()
-        gamma : Vector Matrix R := structuralConstants b
-        listOfNumbers : List String :=  [STRINGIMAGE(q)$Lisp for q in 1..n]
-        symbolsForCoef : Vector Symbol :=
-          [concat("%", concat("x", i))::Symbol  for i in listOfNumbers]
-        xx : M P R
-        mo : P R
-        x : M P R := new(1,n,0)
-        for i in 1..n repeat
-          mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
-          qsetelt_!(x,1,i,mo)
-        y : M P R := copy x
-        k  : PositiveInteger := 1
-        cond : M P R := copy x
-        -- multiplication in the generic algebra means using
-        -- the structural matrices as bilinear forms.
-        -- left multiplication by x, we prepare for that:
-        genGamma : V M P R :=  coerceP$CVMP gamma
-        x := reduce(horizConcat,[genGamma(i)*transpose x for i in 1..#genGamma])
-        while rank(cond) = k repeat
-          k := k+1
-          for i in 1..n repeat
-            setelt(xx,[1],[i],y * transpose x)
-          y := copy xx
-          cond := horizConcat(cond, xx)
-        vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
-        res : SparseUnivariatePolynomial P R := 0
-        for i in 1..k repeat
-         res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial  P R)
-        res
-
-      leftUnitsInternal : () -> REC
-      leftUnitsInternal() ==
-        n := rank()
-        b := basis()
-        gamma : Vector Matrix R := structuralConstants b
-        cond : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
-        rhs : Vector(R) := new(n**2,0$R)$Vector(R)
-        z : Integer := 0
-        addOn : R := 0
-        for k in 1..n repeat
-         for i in 1..n repeat
-           z := z+1   -- index for the rows
-           addOn :=
-             k=i => 1
-             0
-           setelt(rhs,z,addOn)$Vector(R)
-           for j in 1..n repeat  -- index for the columns
-             setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
-        solve(cond,rhs)$LSMP
-
-
-      leftUnit() ==
-        res : REC := leftUnitsInternal()
-        res.particular case "failed" =>
-          messagePrint("this algebra has no left unit")$OutputForm
-          "failed"
-        represents (res.particular :: V R)
-
-      leftUnits() ==
-        res : REC := leftUnitsInternal()
-        res.particular case "failed" =>
-          messagePrint("this algebra has no left unit")$OutputForm
-          "failed"
-        [represents(res.particular :: V R)$%, _
-          map(represents, res.basis)$ListFunctions2(Vector R, %) ]
-
-      rightUnitsInternal : () -> REC
-      rightUnitsInternal() ==
-        n := rank()
-        b := basis()
-        gamma : Vector Matrix R := structuralConstants b
-        condo : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
-        rhs : Vector(R) := new(n**2,0$R)$Vector(R)
-        z : Integer := 0
-        addOn : R := 0
-        for k in 1..n repeat
-         for i in 1..n repeat
-           z := z+1   -- index for the rows
-           addOn :=
-             k=i => 1
-             0
-           setelt(rhs,z,addOn)$Vector(R)
-           for j in 1..n repeat  -- index for the columns
-             setelt(condo,z,j,elt(gamma.k,i,j))$Matrix(R)
-        solve(condo,rhs)$LSMP
-
-      rightUnit() ==
-        res : REC := rightUnitsInternal()
-        res.particular case "failed" =>
-          messagePrint("this algebra has no right unit")$OutputForm
-          "failed"
-        represents (res.particular :: V R)
-
-      rightUnits() ==
-        res : REC := rightUnitsInternal()
-        res.particular case "failed" =>
-          messagePrint("this algebra has no right unit")$OutputForm
-          "failed"
-        [represents(res.particular :: V R)$%, _
-          map(represents, res.basis)$ListFunctions2(Vector R, %) ]
-
-      unit() ==
-        n := rank()
-        b := basis()
-        gamma : Vector Matrix R := structuralConstants b
-        cond : Matrix(R) := new(2*n**2,n,0$R)$Matrix(R)
-        rhs : Vector(R) := new(2*n**2,0$R)$Vector(R)
-        z : Integer := 0
-        u : Integer := n*n
-        addOn : R := 0
-        for k in 1..n repeat
-         for i in 1..n repeat
-           z := z+1   -- index for the rows
-           addOn :=
-             k=i => 1
-             0
-           setelt(rhs,z,addOn)$Vector(R)
-           setelt(rhs,u,addOn)$Vector(R)
-           for j in 1..n repeat  -- index for the columns
-             setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
-             setelt(cond,u,j,elt(gamma.k,i,j))$Matrix(R)
-        res : REC := solve(cond,rhs)$LSMP
-        res.particular case "failed" =>
-          messagePrint("this algebra has no unit")$OutputForm
-          "failed"
-        represents (res.particular :: V R)
-    apply(m:Matrix(R),a:%) ==
-      v : Vector R := coordinates(a)
-      v := m *$Matrix(R) v
-      convert v
-
-
-    structuralConstants()   == structuralConstants basis()
-    conditionsForIdempotents() == conditionsForIdempotents basis()
-    convert(x:%):Vector(R)  == coordinates(x, basis())
-    convert(v:Vector R):%   == represents(v, basis())
-    leftTraceMatrix()       == leftTraceMatrix basis()
-    rightTraceMatrix()      == rightTraceMatrix basis()
-    leftDiscriminant()      == leftDiscriminant basis()
-    rightDiscriminant()     == rightDiscriminant basis()
-    leftRegularRepresentation x == leftRegularRepresentation(x, basis())
-    rightRegularRepresentation x == rightRegularRepresentation(x, basis())
-    coordinates x           == coordinates(x, basis())
-    represents(v:Vector R):%== represents(v, basis())
-
-    coordinates(v:Vector %) ==
-      m := new(#v, rank(), 0)$Matrix(R)
-      for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
-        setRow_!(m, j, coordinates qelt(v, i))
-      m
-
-@
-\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 MONAD Monad>>
-<<category MONADWU MonadWithUnit>>
-<<category NARNG NonAssociativeRng>>
-<<category NASRING NonAssociativeRing>>
-<<category NAALG NonAssociativeAlgebra>>
-<<category FINAALG FiniteRankNonAssociativeAlgebra>>
-<<category FRNAALG FramedNonAssociativeAlgebra>>
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}
