axiom-developer
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Axiom-developer] 20080918.02.tpd.patch (bookvol10.2 add FINITE, ORDSET,


From: daly
Subject: [Axiom-developer] 20080918.02.tpd.patch (bookvol10.2 add FINITE, ORDSET, SGROUP)
Date: Fri, 19 Sep 2008 02:24:39 -0500

=================================================================
diff --git a/books/bookvol10.2.pamphlet b/books/bookvol10.2.pamphlet
index 87e140e..2e31015 100644
--- a/books/bookvol10.2.pamphlet
+++ b/books/bookvol10.2.pamphlet
@@ -391,7 +391,8 @@ CoercibleTo(S:Type): Category == with
 
 @
 <<KOERCE.dotabb>>=
-"KOERCE" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=KOERCE"];
+"KOERCE"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=KOERCE"];
 "KOERCE" -> "CATEGORY"
 
 @
@@ -575,7 +576,8 @@ This is directly exported but not implemented:
 ++ An eltable over domains D and I is a structure which can be viewed
 ++ as a function from D to I.
 ++ Examples of eltable structures range from data structures, e.g. those
-++ of type \spadtype{List}, to algebraic structures like \spadtype{Polynomial}.
+++ of type \spadtype{List}, to algebraic structures like 
+++ \spadtype{Polynomial}.
 Eltable(S:SetCategory, Index:Type): Category == with
   elt : (%, S) -> Index
      ++ elt(u,i) (also written: u . i) returns the element of u indexed by i.
@@ -825,9 +827,11 @@ Aggregate: Category == Type with
      ++ more?(u,n) tests if u has greater than n elements.
    size?: (%,NonNegativeInteger) -> Boolean
      ++ size?(u,n) tests if u has exactly n elements.
-   sample: constant -> %    ++ sample yields a value of type %
+   sample: constant -> %
+     ++ sample yields a value of type %
    if % has finiteAggregate then
-     "#": % -> NonNegativeInteger     ++ # u returns the number of items in u.
+     "#": % -> NonNegativeInteger
+       ++ # u returns the number of items in u.
  add
   eq?(a,b) == EQ(a,b)$Lisp
   sample() == empty()
@@ -916,9 +920,9 @@ This export comes from Eltable:
 ++ References:
 ++ Description:
 ++ An eltable aggregate is one which can be viewed as a function.
-++ For example, the list \axiom{[1,7,4]} can applied to 0,1, and 2 respectively
-++ will return the integers 1,7, and 4; thus this list may be viewed
-++ as mapping 0 to 1, 1 to 7 and 2 to 4. In general, an aggregate
+++ For example, the list \axiom{[1,7,4]} can applied to 0,1, and 2 
+++ respectively will return the integers 1,7, and 4; thus this list may 
+++ be viewed as mapping 0 to 1, 1 to 7 and 2 to 4. In general, an aggregate
 ++ can map members of a domain {\em Dom} to an image domain {\em Im}.
 EltableAggregate(Dom:SetCategory, Im:Type): Category ==
 -- This is separated from Eltable
@@ -932,10 +936,10 @@ EltableAggregate(Dom:SetCategory, Im:Type): Category ==
        ++ to the power n, returning 0 when n is out of range.
     qelt: (%, Dom) -> Im
        ++ qelt(u, x) applies \axiom{u} to \axiom{x} without checking whether
-       ++ \axiom{x} is in the domain of \axiom{u}.  If \axiom{x} is not in the
-       ++ domain of \axiom{u} a memory-access violation may occur.  If a check
-       ++ on whether \axiom{x} is in the domain of \axiom{u} is required, use
-       ++ the function \axiom{elt}.
+       ++ \axiom{x} is in the domain of \axiom{u}.  If \axiom{x} is not 
+       ++ in the domain of \axiom{u} a memory-access violation may occur. 
+       ++ If a check on whether \axiom{x} is in the domain of \axiom{u} 
+       ++ is required, use the function \axiom{elt}.
     if % has shallowlyMutable then
        setelt : (%, Dom, Im) -> Im
           ++ setelt(u,x,y) sets the image of x to be y under u,
@@ -943,9 +947,9 @@ EltableAggregate(Dom:SetCategory, Im:Type): Category ==
           ++ Error: if x is not in the domain of u.
           -- this function will soon be renamed as setelt!.
        qsetelt_!: (%, Dom, Im) -> Im
-          ++ qsetelt!(u,x,y) sets the image of \axiom{x} to be \axiom{y} under
-           ++ \axiom{u}, without checking that \axiom{x} is in the domain of
-           ++ \axiom{u}.
+          ++ qsetelt!(u,x,y) sets the image of \axiom{x} to be \axiom{y} 
+           ++ under \axiom{u}, without checking that \axiom{x} is in 
+           ++ the domain of \axiom{u}.
            ++ If such a check is required use the function \axiom{setelt}.
  add
   qelt(a, x) == elt(a, x)
@@ -954,7 +958,8 @@ EltableAggregate(Dom:SetCategory, Im:Type): Category ==
 
 @
 <<ELTAGG.dotabb>>=
-"ELTAGG" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ELTAGG"];
+"ELTAGG"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ELTAGG"];
 "ELTAGG" -> "ELTAB"
 
 @
@@ -986,7 +991,10 @@ digraph pic {
 
 {\bf See:}\\
 \pageto{AbelianSemiGroup}{ABELSG}
+\pageto{Finite}{FINITE}
 \pageto{HomogeneousAggregate}{HOAGG}
+\pageto{OrderedSet}{ORDSET}
+\pageto{SemiGroup}{SGROUP}
 
 {\bf Exports:}\\
 \begin{tabular}{lllll}
@@ -1030,7 +1038,8 @@ These exports come from CoercibleTo(OutputForm):
 ++ References:
 ++ Description:
 ++ \spadtype{SetCategory} is the basic category for describing a collection
-++ of elements with \spadop{=} (equality) and \spadfun{coerce} to output form.
+++ of elements with \spadop{=} (equality) and \spadfun{coerce} to 
+++ output form.
 ++
 ++ Conditional Attributes:
 ++    canonical\tab{15}data structure equality is the same as \spadop{=}
@@ -1045,7 +1054,8 @@ SetCategory(): Category == Join(BasicType,CoercibleTo 
OutputForm) with
 
 @
 <<SETCAT.dotabb>>=
-"SETCAT" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SETCAT"];
+"SETCAT"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SETCAT"];
 "SETCAT" -> "BASTYPE"
 "SETCAT" -> "KOERCE"
 
@@ -1143,8 +1153,8 @@ AbelianSemiGroup(): Category == SetCategory with
     --operations
       "+": (%,%) -> %                  ++ x+y computes the sum of x and y.
       "*": (PositiveInteger,%) -> %
-        ++ n*x computes the left-multiplication of x by the positive integer n.
-        ++ This is equivalent to adding x to itself n times.
+        ++ n*x computes the left-multiplication of x by the positive 
+        ++ integer n. This is equivalent to adding x to itself n times.
     add
       import RepeatedDoubling(%)
       if not (% has Ring) then
@@ -1152,7 +1162,8 @@ AbelianSemiGroup(): Category == SetCategory with
 
 @
 <<ABELSG.dotabb>>=
-"ABELSG" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ABELSG"];
+"ABELSG"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ABELSG"];
 "ABELSG" -> "SETCAT"
 "ABELSG" -> "REPDB"
 
@@ -1161,7 +1172,7 @@ AbelianSemiGroup(): Category == SetCategory with
 "AbelianSemiGroup()"
  [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ABELSG"];
 "AbelianSemiGroup()" -> "SetCategory()"
-"AbelianSemiGroup()" -> "RepeatedDoubling(S:SetCategory)"
+"AbelianSemiGroup()" -> "RepeatedDoubling(SetCategory)"
 
 <<ABELSG.dotpic>>=
 digraph pic {
@@ -1171,7 +1182,7 @@ digraph pic {
 
 "AbelianSemiGroup()" [color=lightblue];
 "AbelianSemiGroup()" -> "SetCategory()"
-"AbelianSemiGroup()" -> "RepeatedDoubling(S:AbelianSemiGroup)"
+"AbelianSemiGroup()" -> "RepeatedDoubling(AbelianSemiGroup)"
 
 "SetCategory()" [color=lightblue];
 "SetCategory()" -> "BasicType()"
@@ -1187,11 +1198,11 @@ digraph pic {
 "CoercibleTo(a:Type)" [color=lightblue];
 "CoercibleTo(a:Type)" -> "Category"
 
-"RepeatedDoubling(S:AbelianSemiGroup)" [color="#00EE00"];
-"RepeatedDoubling(S:AbelianSemiGroup)" -> "RepeatedDoubling(S:SetCategory)"
+"RepeatedDoubling(AbelianSemiGroup)" [color="#00EE00"];
+"RepeatedDoubling(AbelianSemiGroup)" -> "RepeatedDoubling(a:SetCategory)"
 
-"RepeatedDoubling(S:SetCategory)" [color="#00EE00"];
-"RepeatedDoubling(S:SetCategory)" -> "Package"
+"RepeatedDoubling(a:SetCategory)" [color="#00EE00"];
+"RepeatedDoubling(a:SetCategory)" -> "Package"
 
 "Package" [color="#00EE00"];
 
@@ -1199,7 +1210,122 @@ digraph pic {
 }
 
 @
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{Finite}{FINITE}
+\pagepic{ps/v102finite.ps}{FINITE}
+
+{\bf See:}\\
+\pagefrom{SetCategory}{SETCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{lllllllll}
+ coerce & hash & index & latex & lookup & random & size & ?=? & ?\~{}=?
+\end{tabular}
 
+\cross{FINITE}{coerce}
+\cross{FINITE}{hash}
+\cross{FINITE}{index}
+\cross{FINITE}{latex}
+\cross{FINITE}{lookup}
+\cross{FINITE}{random}
+\cross{FINITE}{size}
+\cross{FINITE}{?=?}
+\cross{FINITE}{?\~{}=?}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ index : PositiveInteger -> %
+ lookup : % -> PositiveInteger
+ random : () -> %                     
+ size : () -> NonNegativeInteger
+\end{verbatim}
+
+These exports come from SetCategory():
+\begin{verbatim}
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger            
+ latex : % -> String                  
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+\end{verbatim}
+
+<<category FINITE Finite>>=
+)abbrev category FINITE Finite
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of domains composed of a finite set of elements.
+++ We include the functions \spadfun{lookup} and \spadfun{index} 
+++ to give a bijection between the finite set and an initial 
+++ segment of positive integers.
+++
+++ Axioms:
+++   \spad{lookup(index(n)) = n}
+++   \spad{index(lookup(s)) = s}
+
+Finite(): Category == SetCategory with
+    --operations
+      size: () ->  NonNegativeInteger
+        ++ size() returns the number of elements in the set.
+      index: PositiveInteger -> %
+        ++ index(i) takes a positive integer i less than or equal
+        ++ to \spad{size()} and
+        ++ returns the \spad{i}-th element of the set. 
+        ++ This operation establishs a bijection
+        ++ between the elements of the finite set and \spad{1..size()}.
+      lookup: % -> PositiveInteger
+        ++ lookup(x) returns a positive integer such that
+        ++ \spad{x = index lookup x}.
+      random: () -> %
+        ++ random() returns a random element from the set.
+
+@
+<<FINITE.dotabb>>=
+"FINITE"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=FINITE"];
+"FINITE" -> "SETCAT"
+
+@
+<<FINITE.dotfull>>=
+"Finite()"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=FINITE"];
+"Finite()" -> "SetCategory()"
+
+@
+<<FINITE.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"Finite()" [color=lightblue];
+"Finite()" -> "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}
@@ -1402,7 +1528,18 @@ digraph pic {
 
 "Evalable(a:Type)" [color="#00EE00"];
 
-"SetCategory()" [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()"
@@ -1415,6 +1552,274 @@ digraph pic {
 }
 
 @
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagehead{OrderedSet}{ORDSET}
+\pagepic{ps/v102orderedset.ps}{ORDSET}
+
+{\bf See:}\\
+\pagefrom{SetCategory}{SETCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llllll}
+ coerce & hash & latex & max & min & ?<?\\
+ ?<=? & ?=? & ?>? & ?>=? & ?\~{}=? &\\
+\end{tabular}
+
+\cross{ORDSET}{coerce}
+\cross{ORDSET}{hash}
+\cross{ORDSET}{latex}
+\cross{ORDSET}{max}
+\cross{ORDSET}{min}
+\cross{ORDSET}{?<?}
+\cross{ORDSET}{?<=?}
+\cross{ORDSET}{?=?}
+\cross{ORDSET}{?>?}
+\cross{ORDSET}{?>=?}
+\cross{ORDSET}{?\~{}=?}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ ?<? : (%,%) -> Boolean               
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ max : (%,%) -> %                     
+ min : (%,%) -> %
+ ?>? : (%,%) -> Boolean
+ ?>=? : (%,%) -> Boolean              
+ ?<=? : (%,%) -> Boolean
+\end{verbatim}
+
+These exports come from SetCategory():
+\begin{verbatim}
+ coerce : % -> OutputForm
+ hash : % -> SingleInteger            
+ latex : % -> String
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean              
+\end{verbatim}
+
+<<category ORDSET OrderedSet>>=
+)abbrev category ORDSET OrderedSet
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of totally ordered sets, that is, sets such that for each 
+++ pair of elements \spad{(a,b)}
+++ exactly one of the following relations holds \spad{a<b or a=b or b<a}
+++ and the relation is transitive, i.e.  \spad{a<b and b<c => a<c}.
+
+OrderedSet(): Category == SetCategory with
+  --operations
+    "<": (%,%) -> Boolean
+      ++ x < y is a strict total ordering on the elements of the set.
+    ">":         (%, %) -> Boolean
+      ++ x > y is a greater than test.
+    ">=":        (%, %) -> Boolean
+      ++ x >= y is a greater than or equal test.
+    "<=":        (%, %) -> Boolean
+      ++ x <= y is a less than or equal test.
+
+    max: (%,%) -> %
+      ++ max(x,y) returns the maximum of x and y relative to "<".
+    min: (%,%) -> %
+      ++ min(x,y) returns the minimum of x and y relative to "<".
+  add
+  --declarations
+    x,y: %
+  --definitions
+  -- These really ought to become some sort of macro
+    max(x,y) ==
+      x > y => x
+      y
+    min(x,y) ==
+      x > y => y
+      x
+    ((x: %) >  (y: %)) : Boolean == y < x
+    ((x: %) >= (y: %)) : Boolean == not (x < y)
+    ((x: %) <= (y: %)) : Boolean == not (y < x)
+
+@
+<<ORDSET.dotabb>>=
+"ORDSET" 
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ORDSET"];
+"ORDSET" -> "SETCAT"
+
+@
+<<ORDSET.dotfull>>=
+"OrderedSet()"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=ORDSET"];
+"OrderedSet()" -> "SetCategory()"
+
+@
+<<ORDSET.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"OrderedSet()" [color=lightblue];
+"OrderedSet()" -> "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{SemiGroup}{SGROUP}
+%\pagepic{ps/v102semigroup.ps}{SGROUP}
+\includegraphics[scale=0.75]{ps/v102semigroup.ps}
+\index{images!SGROUP}
+
+A Semigroup is defined as a set $S$ with a binary multiplicative
+operator ``*''. A Semigroup $G(S,*)$ is:
+\begin{itemize}
+\item a set $S$ which can be null
+\item a binary multiplicative operator ``*''
+\item associative. $\forall a,b,c \in S, a*(b*c) = (a*b)*c$
+\end{itemize}
+
+{\bf See:}\\
+\pagefrom{SetCategory}{SETCAT}
+
+{\bf Exports:}\\
+\begin{tabular}{llll}
+ coerce & hash & latex & ?*? \\
+ ?**?   & ?=?  & ?\^{}?   & ?\~{}=?
+\end{tabular}
+
+\cross{SGROUP}{coerce}
+\cross{SGROUP}{hash}
+\cross{SGROUP}{latex}
+\cross{SGROUP}{?*?}
+\cross{SGROUP}{?**?}
+\cross{SGROUP}{?=?}
+\cross{SGROUP}{?\^{}?}
+\cross{SGROUP}{?~=?}
+
+These are directly exported but not implemented:
+\begin{verbatim}
+ ?*? : (%,%) -> %                     
+\end{verbatim}
+
+These are implemented by this category:
+\begin{verbatim}
+ ?**? : (%,PositiveInteger) -> %
+ ?^? : (%,PositiveInteger) -> %
+\end{verbatim}
+
+These exports come from SetCategory():
+\begin{verbatim}
+ coerce : % -> OutputForm             
+ hash : % -> SingleInteger
+ latex : % -> String                  
+ ?=? : (%,%) -> Boolean               
+ ?~=? : (%,%) -> Boolean
+\end{verbatim}
+
+<<category SGROUP SemiGroup>>=
+)abbrev category SGROUP SemiGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ the class of all multiplicative semigroups, i.e. a set
+++ with an associative operation \spadop{*}.
+++
+++ Axioms:
+++    \spad{associative("*":(%,%)->%)}\tab{30}\spad{ (x*y)*z = x*(y*z)}
+++
+++ Conditional attributes:
+++    \spad{commutative("*":(%,%)->%)}\tab{30}\spad{ x*y = y*x }
+SemiGroup(): Category == SetCategory with
+    --operations
+      "*": (%,%) -> %                  ++ x*y returns the product of x and y.
+      "**": (%,PositiveInteger) -> %   ++ x**n returns the repeated product
+                                       ++ of x n times, i.e. exponentiation.
+      "^": (%,PositiveInteger) -> %    ++ x^n returns the repeated product
+                                       ++ of x n times, i.e. exponentiation.
+    add
+      import RepeatedSquaring(%)
+      x:% ** n:PositiveInteger == expt(x,n)
+      _^(x:%, n:PositiveInteger):% == x ** n
+
+@
+<<SGROUP.dotabb>>=
+"SGROUP"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SGROUP"];
+"SGROUP" -> "SETCAT"
+
+@
+<<SGROUP.dotfull>>=
+"SemiGroup()"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SGROUP"];
+"SemiGroup()" -> "SetCategory()"
+"SemiGroup()" -> "RepeatedSquaring(SemiGroup)"
+
+@
+<<SGROUP.dotpic>>=
+digraph pic {
+ fontsize=10;
+ bgcolor="#FFFF66";
+ node [shape=box, color=white, style=filled];
+
+"SemiGroup()" [color=lightblue];
+"SemiGroup()" -> "SetCategory()"
+"SemiGroup()" -> "RepeatedSquaring(SemiGroup)"
+
+"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"
+
+"RepeatedSquaring(SemiGroup)" [color="#00EE00"];
+"RepeatedSquaring(SemiGroup)" -> "RepeatedSquaring(a:SetCategory)"
+
+"RepeatedSquaring(a:SetCategory)" [color="#00EE00"];
+"RepeatedSquaring(a:SetCategory)" -> "Package"
+
+"Package" [color="#00EE00"];
+
+"Category" [color=lightblue];
+
+}
+
+@
 \chapter{Category Layer 4}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \pagehead{BagAggregate}{BGAGG}
@@ -1726,8 +2131,8 @@ Collection(S:Type): Category == HomogeneousAggregate(S) 
with
      ++ \axiom{[x,y,...,z]$D}, where
      ++ D is the domain. D may be omitted for those of type List.
    find: (S->Boolean, %) -> Union(S, "failed")
-     ++ find(p,u) returns the first x in u such that \axiom{p(x)} is true, and
-     ++ "failed" otherwise.
+     ++ find(p,u) returns the first x in u such that \axiom{p(x)} is true, 
+     ++ and "failed" otherwise.
    if % has finiteAggregate then
       reduce: ((S,S)->S,%) -> S
        ++ reduce(f,u) reduces the binary operation f across u. For example,
@@ -1752,13 +2157,13 @@ Collection(S:Type): Category == HomogeneousAggregate(S) 
with
        ++ \axiom{p(x)} is true.
        ++ Note: \axiom{remove(p,u) == [x for x in u | not p(x)]}.
       select: (S->Boolean,%) -> %
-       ++ select(p,u) returns a copy of u containing only those elements such
-       ++ \axiom{p(x)} is true.
+       ++ select(p,u) returns a copy of u containing only those elements 
+       ++ such \axiom{p(x)} is true.
        ++ Note: \axiom{select(p,u) == [x for x in u | p(x)]}.
       if S has SetCategory then
        reduce: ((S,S)->S,%,S,S) -> S
-         ++ reduce(f,u,x,z) reduces the binary operation f across u, stopping
-         ++ when an "absorbing element" z is encountered.
+         ++ reduce(f,u,x,z) reduces the binary operation f across u, 
+         ++ stopping when an "absorbing element" z is encountered.
          ++ As for \axiom{reduce(f,u,x)}, x is the identity operation of f.
          ++ Same as \axiom{reduce(f,u,x)} when u contains no element z.
          ++ Thus the third argument x is returned when u is empty.
@@ -1980,7 +2385,8 @@ IndexedAggregate(Index: SetCategory, Entry: Type): 
Category ==
    entries: % -> List Entry
       ++ entries(u) returns a list of all the entries of aggregate u
       ++ in no assumed order.
-      -- to become entries: % -> Entry* and entries: % -> Iterator(Entry,Entry)
+      -- to become entries: % -> Entry* and 
+      -- entries: % -> Iterator(Entry,Entry)
    index?: (Index,%) -> Boolean
       ++ index?(i,u) tests if i is an index of aggregate u.
    indices: % -> List Index
@@ -2466,8 +2872,8 @@ These exports come from RecursiveAggregate(a:Type)
 ++ Keywords:
 ++ References:
 ++ Description:
-++ A binary-recursive aggregate has 0, 1 or 2 children and
-++ serves as a model for a binary tree or a doubly-linked aggregate structure
+++ A binary-recursive aggregate has 0, 1 or 2 children and serves
+++ as a model for a binary tree or a doubly-linked aggregate structure
 BinaryRecursiveAggregate(S:Type):Category == RecursiveAggregate S with
    -- needs preorder, inorder and postorder iterators
    left: % -> %
@@ -3263,29 +3669,31 @@ LinearAggregate(S:Type): Category ==
       ++ of b followed ... by the elements of c.
       ++ Note: \axiom{concat(a,b,...,c) = concat(a,concat(b,...,c))}.
    map: ((S,S)->S,%,%) -> %
-     ++ map(f,u,v) returns a new collection w with elements \axiom{z = f(x,y)}
-     ++ for corresponding elements x and y from u and v.
+     ++ map(f,u,v) returns a new collection w with elements 
+     ++ \axiom{z = f(x,y)} for corresponding elements x and y from u and v.
      ++ Note: for linear aggregates, \axiom{w.i = f(u.i,v.i)}.
    elt: (%,UniversalSegment(Integer)) -> %
       ++ elt(u,i..j) (also written: \axiom{a(i..j)}) returns the aggregate of
       ++ elements \axiom{u} for k from i to j in that order.
       ++ Note: in general, \axiom{a.s = [a.k for i in s]}.
    delete: (%,Integer) -> %
-      ++ delete(u,i) returns a copy of u with the \axiom{i}th element deleted.
-      ++ Note: for lists, 
+      ++ delete(u,i) returns a copy of u with the \axiom{i}th 
+      ++ element deleted. Note: for lists, 
       ++ \axiom{delete(a,i) == concat(a(0..i - 1),a(i + 1,..))}.
    delete: (%,UniversalSegment(Integer)) -> %
       ++ delete(u,i..j) returns a copy of u with the \axiom{i}th through
       ++ \axiom{j}th element deleted.
       ++ Note: \axiom{delete(a,i..j) = concat(a(0..i-1),a(j+1..))}.
    insert: (S,%,Integer) -> %
-      ++ insert(x,u,i) returns a copy of u having x as its \axiom{i}th element.
+      ++ insert(x,u,i) returns a copy of u having x as its 
+      ++ \axiom{i}th element.
       ++ Note: \axiom{insert(x,a,k) = concat(concat(a(0..k-1),x),a(k..))}.
    insert: (%,%,Integer) -> %
       ++ insert(v,u,k) returns a copy of u having v inserted beginning at the
       ++ \axiom{i}th element.
       ++ Note: \axiom{insert(v,u,k) = concat( u(0..k-1), v, u(k..) )}.
-   if % has shallowlyMutable then setelt: (%,UniversalSegment(Integer),S) -> S
+   if % has shallowlyMutable then 
+    setelt: (%,UniversalSegment(Integer),S) -> S
       ++ setelt(u,i..j,x) (also written: \axiom{u(i..j) := x}) destructively
       ++ replaces each element in the segment \axiom{u(i..j)} by x.
       ++ The value x is returned.
@@ -3475,7 +3883,8 @@ PriorityQueueAggregate(S:OrderedSet): Category == 
BagAggregate S with
 
 @
 <<PRQAGG.dotabb>>=
-"PRQAGG" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=PRQAGG"];
+"PRQAGG"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=PRQAGG"];
 "PRQAGG" -> "BGAGG"
 
 @
@@ -3635,15 +4044,16 @@ These exports come from BagAggregate(a:Type):
 ++ Keywords:
 ++ References:
 ++ Description:
-++ A queue is a bag where the first item inserted is the first item extracted.
+++ A queue is a bag where the first item inserted is the first 
+++ item extracted.
 QueueAggregate(S:Type): Category == BagAggregate S with
    finiteAggregate
    enqueue_!: (S, %) -> S
      ++ enqueue!(x,q) inserts x into the queue q at the back end.
    dequeue_!: % -> S
-     ++ dequeue! s destructively extracts the first (top) element from queue q.
-     ++ The element previously second in the queue becomes the first element.
-     ++ Error: if q is empty.
+     ++ dequeue! s destructively extracts the first (top) element 
+     ++ from queue q. The element previously second in the queue becomes 
+     ++ the first element. Error: if q is empty.
    rotate_!: % -> %
      ++ rotate! q rotates queue q so that the element at the front of
      ++ the queue goes to the back of the queue.
@@ -4056,9 +4466,9 @@ These exports come from RecursiveAggregate(a:Type):
 ++ This aggregate models, though not precisely, a linked
 ++ list possibly with a single cycle.
 ++ A node with one children models a non-empty list, with the
-++ \spadfun{value} of the list designating the head, or \spadfun{first}, of the
-++ list, and the child designating the tail, or \spadfun{rest}, of the list.
-++ A node with no child then designates the empty list.
+++ \spadfun{value} of the list designating the head, or \spadfun{first}, 
+++ of the list, and the child designating the tail, or \spadfun{rest}, 
+++ of the list. A node with no child then designates the empty list.
 ++ Since these aggregates are recursive aggregates, they may be cyclic.
 UnaryRecursiveAggregate(S:Type): Category == RecursiveAggregate S with
    concat: (%,%) -> %
@@ -4713,8 +5123,8 @@ These exports come from QueueAggregate(a:Type):
 ++ References:
 ++ Description:
 ++ A dequeue is a doubly ended stack, that is, a bag where first items
-++ inserted are the first items extracted, at either the front or the back end
-++ of the data structure.
+++ inserted are the first items extracted, at either the front or 
+++ the back end of the data structure.
 DequeueAggregate(S:Type):
  Category == Join(StackAggregate S,QueueAggregate S) with
    dequeue: () -> %
@@ -5017,12 +5427,13 @@ ExtensibleLinearAggregate(S:Type):Category == 
LinearAggregate S with
    insert_!: (S,%,Integer) -> %
      ++ insert!(x,u,i) destructively inserts x into u at position i.
    insert_!: (%,%,Integer) -> %
-     ++ insert!(v,u,i) destructively inserts aggregate v into u at position i.
+     ++ insert!(v,u,i) destructively inserts aggregate v into u 
+     ++ at position i.
    merge_!: ((S,S)->Boolean,%,%) -> %
      ++ merge!(p,u,v) destructively merges u and v using predicate p.
    select_!: (S->Boolean,%) -> %
-     ++ select!(p,u) destructively changes u by keeping only values x such that
-     ++ \axiom{p(x)}.
+     ++ select!(p,u) destructively changes u by keeping only values 
+     ++ x such that \axiom{p(x)}.
    if S has SetCategory then
      remove_!: (S,%) -> %
        ++ remove!(x,u) destructively removes all values x from u.
@@ -5323,16 +5734,17 @@ FiniteLinearAggregate(S:Type): Category == 
LinearAggregate S with
    finiteAggregate
    merge: ((S,S)->Boolean,%,%) -> %
       ++ merge(p,a,b) returns an aggregate c which merges \axiom{a} and b.
-      ++ The result is produced by examining each element x of \axiom{a} and y
-      ++ of b successively. If \axiom{p(x,y)} is true, then x is inserted into
-      ++ the result; otherwise y is inserted. If x is chosen, the next element
-      ++ of \axiom{a} is examined, and so on. When all the elements of one
-      ++ aggregate are examined, the remaining elements of the other
-      ++ are appended.
+      ++ The result is produced by examining each element x of \axiom{a} 
+      ++ and y of b successively. If \axiom{p(x,y)} is true, then x is 
+      ++ inserted into the result; otherwise y is inserted. If x is 
+      ++ chosen, the next element of \axiom{a} is examined, and so on. 
+      ++ When all the elements of one aggregate are examined, the 
+      ++ remaining elements of the other are appended.
       ++ For example, \axiom{merge(<,[1,3],[2,7,5])} returns 
       ++ \axiom{[1,2,3,7,5]}.
    reverse: % -> %
-      ++ reverse(a) returns a copy of \axiom{a} with elements in reverse order.
+      ++ reverse(a) returns a copy of \axiom{a} with elements 
+      ++ in reverse order.
    sort: ((S,S)->Boolean,%) -> %
       ++ sort(p,a) returns a copy of \axiom{a} sorted using total ordering 
       ++ predicate p.
@@ -5344,11 +5756,11 @@ FiniteLinearAggregate(S:Type): Category == 
LinearAggregate S with
       ++ if there is no such x.
    if S has SetCategory then
       position: (S, %) -> Integer
-       ++ position(x,a) returns the index i of the first occurrence of x in a,
-       ++ and \axiom{minIndex(a) - 1} if there is no such x.
+       ++ position(x,a) returns the index i of the first occurrence of 
+       ++ x in a, and \axiom{minIndex(a) - 1} if there is no such x.
       position: (S,%,Integer) -> Integer
-       ++ position(x,a,n) returns the index i of the first occurrence of x in
-       ++ \axiom{a} where \axiom{i >= n}, and \axiom{minIndex(a) - 1} 
+       ++ position(x,a,n) returns the index i of the first occurrence of 
+       ++ x in \axiom{a} where \axiom{i >= n}, and \axiom{minIndex(a) - 1} 
         ++ if no such x is found.
    if S has OrderedSet then
       OrderedSet
@@ -5755,14 +6167,16 @@ These are implemented by this category:
  map! : ((S -> S),%) -> % if $ has shallowlyMutable
  possiblyInfinite? : % -> Boolean
  setelt : (%,Integer,S) -> S if $ has shallowlyMutable
- setelt : (%,UniversalSegment Integer,S) -> S if $ has shallowlyMutable
+ setelt : (%,UniversalSegment Integer,S) -> S 
+          if $ has shallowlyMutable
  ?.? : (%,Integer) -> S
  ?.? : (%,UniversalSegment Integer) -> %
 \end{verbatim}
 
 These exports come from UnaryRecursiveAggregate(a:Type):
 \begin{verbatim}
- any? : ((S -> Boolean),%) -> Boolean if $ has finiteAggregate
+ any? : ((S -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
  children : % -> List %               
  child? : (%,%) -> Boolean if S has SETCAT
  coerce : % -> OutputForm if S has SETCAT
@@ -5770,8 +6184,11 @@ These exports come from UnaryRecursiveAggregate(a:Type):
  concat : (%,S) -> %
  concat! : (%,S) -> % if $ has shallowlyMutable
  copy : % -> %                        
- count : (S,%) -> NonNegativeInteger if S has SETCAT and $ has finiteAggregate
- count : ((S -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ count : (S,%) -> NonNegativeInteger 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ count : ((S -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
  cycleEntry : % -> %
  cycleLength : % -> NonNegativeInteger
  cycleSplit! : % -> % if $ has shallowlyMutable
@@ -5781,11 +6198,20 @@ These exports come from UnaryRecursiveAggregate(a:Type):
  empty : () -> %                      
  empty? : % -> Boolean
  eq? : (%,%) -> Boolean
- eval : (%,List S,List S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,S,S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,Equation S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,List Equation S) -> % if S has EVALAB S and S has SETCAT
- every? : ((S -> Boolean),%) -> Boolean if $ has finiteAggregate
+ eval : (%,List S,List S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,S,S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,Equation S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,List Equation S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ every? : ((S -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
  first : % -> S
  hash : % -> SingleInteger if S has SETCAT
  latex : % -> String if S has SETCAT
@@ -5795,7 +6221,9 @@ These exports come from UnaryRecursiveAggregate(a:Type):
  leaves : % -> List S                 
  less? : (%,NonNegativeInteger) -> Boolean
  map : ((S -> S),%) -> %              
- member? : (S,%) -> Boolean if S has SETCAT and $ has finiteAggregate
+ member? : (S,%) -> Boolean 
+          if S has SETCAT 
+          and $ has finiteAggregate
  members : % -> List S if $ has finiteAggregate
  more? : (%,NonNegativeInteger) -> Boolean
  nodes : % -> List %                  
@@ -5843,19 +6271,33 @@ These exports come from LinearAggregate(a:Type):
  qelt : (%,Integer) -> S              
  convert : % -> InputForm if S has KONVERT INFORM
  delete : (%,UniversalSegment Integer) -> %
- entry? : (S,%) -> Boolean if $ has finiteAggregate and S has SETCAT
+ entry? : (S,%) -> Boolean 
+          if $ has finiteAggregate 
+          and S has SETCAT
  find : ((S -> Boolean),%) -> Union(S,"failed")
  maxIndex : % -> Integer if Integer has ORDSET
  minIndex : % -> Integer if Integer has ORDSET
- qsetelt! : (%,Integer,S) -> S if $ has shallowlyMutable
- reduce : (((S,S) -> S),%,S,S) -> S if S has SETCAT and $ has finiteAggregate
- reduce : (((S,S) -> S),%,S) -> S if $ has finiteAggregate
- reduce : (((S,S) -> S),%) -> S if $ has finiteAggregate
- remove : (S,%) -> % if S has SETCAT and $ has finiteAggregate
- remove : ((S -> Boolean),%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % if S has SETCAT and $ has finiteAggregate
- select : ((S -> Boolean),%) -> % if $ has finiteAggregate
- swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
+ qsetelt! : (%,Integer,S) -> S 
+          if $ has shallowlyMutable
+ reduce : (((S,S) -> S),%,S,S) -> S 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ reduce : (((S,S) -> S),%,S) -> S 
+          if $ has finiteAggregate
+ reduce : (((S,S) -> S),%) -> S 
+          if $ has finiteAggregate
+ remove : (S,%) -> % 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ remove : ((S -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ select : ((S -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ swap! : (%,Integer,Integer) -> Void 
+          if $ has shallowlyMutable
 \end{verbatim}
 
 <<category STAGG StreamAggregate>>=
@@ -6223,10 +6665,10 @@ These exports come from FiniteLinearAggregate(a:Type):
 ++ with the \spadatt{shallowlyMutable} property, that is, any component of
 ++ the array may be changed without affecting the
 ++ identity of the overall array.
-++ Array data structures are typically represented by a fixed area in storage 
-++ and cannot efficiently grow or shrink on demand as can list structures
-++ (see however \spadtype{FlexibleArray} for a data structure which
-++ is a cross between a list and an array).
+++ Array data structures are typically represented by a fixed area in 
+++ storage and cannot efficiently grow or shrink on demand as can list 
+++ structures (see however \spadtype{FlexibleArray} for a data structure 
+++ which is a cross between a list and an array).
 ++ Iteration over, and access to, elements of arrays is extremely fast
 ++ (and often can be optimized to open-code).
 ++ Insertion and deletion however is generally slow since an entirely new
@@ -6889,21 +7331,28 @@ These are implemented by this category:
  new : (NonNegativeInteger,S) -> %
  position : ((S -> Boolean),%) -> Integer
  position : (S,%,Integer) -> Integer if S has SETCAT
- reduce : (((S,S) -> S),%,S) -> S if $ has finiteAggregate
- reduce : (((S,S) -> S),%,S,S) -> S if S has SETCAT and $ has finiteAggregate
- reduce : (((S,S) -> S),%) -> S if $ has finiteAggregate
+ reduce : (((S,S) -> S),%,S) -> S 
+          if $ has finiteAggregate
+ reduce : (((S,S) -> S),%,S,S) -> S 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ reduce : (((S,S) -> S),%) -> S 
+          if $ has finiteAggregate
  remove! : ((S -> Boolean),%) -> %
  removeDuplicates! : % -> % if S has SETCAT
  reverse! : % -> % if $ has shallowlyMutable
- select : ((S -> Boolean),%) -> % if $ has finiteAggregate
- sort! : (((S,S) -> Boolean),%) -> % if $ has shallowlyMutable
+ select : ((S -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ sort! : (((S,S) -> Boolean),%) -> % 
+          if $ has shallowlyMutable
  sorted? : (((S,S) -> Boolean),%) -> Boolean
  ?<? : (%,%) -> Boolean if S has ORDSET
 \end{verbatim}
 
 These exports come from StreamAggregate(a:Type):
 \begin{verbatim}
- any? : ((S -> Boolean),%) -> Boolean if $ has finiteAggregate
+ any? : ((S -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
  children : % -> List %               
  child? : (%,%) -> Boolean if S has SETCAT
  coerce : % -> OutputForm if S has SETCAT
@@ -6915,8 +7364,11 @@ These exports come from StreamAggregate(a:Type):
  concat! : (%,%) -> %                 
  construct : List S -> %
  convert : % -> InputForm if S has KONVERT INFORM
- count : (S,%) -> NonNegativeInteger if S has SETCAT and $ has finiteAggregate
- count : ((S -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
+ count : (S,%) -> NonNegativeInteger 
+          if S has SETCAT 
+          and $ has finiteAggregate
+ count : ((S -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
  cycleEntry : % -> %
  cycleLength : % -> NonNegativeInteger
  cycleSplit! : % -> % if $ has shallowlyMutable
@@ -6928,14 +7380,25 @@ These exports come from StreamAggregate(a:Type):
  elt : (%,Integer,S) -> S
  empty : () -> %
  empty? : % -> Boolean                
- entry? : (S,%) -> Boolean if $ has finiteAggregate and S has SETCAT
+ entry? : (S,%) -> Boolean 
+          if $ has finiteAggregate 
+          and S has SETCAT
  entries : % -> List S
  eq? : (%,%) -> Boolean               
- eval : (%,List S,List S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,S,S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,Equation S) -> % if S has EVALAB S and S has SETCAT
- eval : (%,List Equation S) -> % if S has EVALAB S and S has SETCAT
- every? : ((S -> Boolean),%) -> Boolean if $ has finiteAggregate
+ eval : (%,List S,List S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,S,S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,Equation S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ eval : (%,List Equation S) -> % 
+          if S has EVALAB S 
+          and S has SETCAT
+ every? : ((S -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
  explicitlyFinite? : % -> Boolean
  fill! : (%,S) -> % if $ has shallowlyMutable
  first : % -> S                       
@@ -6954,7 +7417,9 @@ These exports come from StreamAggregate(a:Type):
  map : ((S -> S),%) -> %              
  map! : ((S -> S),%) -> % if $ has shallowlyMutable
  maxIndex : % -> Integer if Integer has ORDSET
- member? : (S,%) -> Boolean if S has SETCAT and $ has finiteAggregate
+ member? : (S,%) -> Boolean 
+          if S has SETCAT 
+          and $ has finiteAggregate
  members : % -> List S if $ has finiteAggregate
  minIndex : % -> Integer if Integer has ORDSET
  more? : (%,NonNegativeInteger) -> Boolean
@@ -6964,16 +7429,21 @@ These exports come from StreamAggregate(a:Type):
  possiblyInfinite? : % -> Boolean
  qelt : (%,Integer) -> S              
  qsetelt! : (%,Integer,S) -> S if $ has shallowlyMutable
- remove : (S,%) -> % if S has SETCAT and $ has finiteAggregate
+ remove : (S,%) -> % 
+          if S has SETCAT 
+          and $ has finiteAggregate
  remove : ((S -> Boolean),%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % if S has SETCAT and $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if S has SETCAT 
+          and $ has finiteAggregate
  rest : % -> %
  rest : (%,NonNegativeInteger) -> %
  sample : () -> %
  second : % -> S                      
  setchildren! : (%,List %) -> % if $ has shallowlyMutable
  setelt : (%,Integer,S) -> S if $ has shallowlyMutable
- setelt : (%,UniversalSegment Integer,S) -> S if $ has shallowlyMutable
+ setelt : (%,UniversalSegment Integer,S) -> S 
+          if $ has shallowlyMutable
  setelt : (%,last,S) -> S if $ has shallowlyMutable
  setelt : (%,rest,%) -> % if $ has shallowlyMutable
  setelt : (%,first,S) -> S if $ has shallowlyMutable
@@ -7050,7 +7520,8 @@ ListAggregate(S:Type): Category == Join(StreamAggregate S,
    sort_!(f, l)              == mergeSort(f, l, #l)
    list x                 == concat(x, empty())
    reduce(f, x)                   ==
-     empty? x => error "reducing over an empty list needs the 3 argument form"
+     empty? x => _
+       error "reducing over an empty list needs the 3 argument form"
      reduce(f, rest x, first x)
    merge(f, p, q)         == merge_!(f, copy p, copy q)
 
@@ -7842,65 +8313,116 @@ These are implemented by this category:
 \end{verbatim}
 
 These exports come from KeyedDictionary(Key,Entry)\\
-where Key:SetCategory and Entry:SetCategory:
+where Key:SetCategory and Entry:SetCategory\\
+and RECKEYENTRY=Record(key: Key,entry: Entry):
 \begin{verbatim}
- any? : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Boolean if $ has 
finiteAggregate
- bag : List Record(key: Key,entry: Entry) -> %
- construct : List Record(key: Key,entry: Entry) -> %
- convert : % -> InputForm if Record(key: Key,entry: Entry) has KONVERT INFORM
+ any? : ((RECKEYENTRY -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ bag : List RECKEYENTRY -> %
+ construct : List RECKEYENTRY -> %
+ convert : % -> InputForm if RECKEYENTRY has KONVERT INFORM
  copy : % -> %                        
- count : (Entry,%) -> NonNegativeInteger if Entry has SETCAT and $ has 
finiteAggregate
- count : ((Record(key: Key,entry: Entry) -> Boolean),%) -> NonNegativeInteger 
if $ has finiteAggregate
+ count : (Entry,%) -> NonNegativeInteger 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ count : ((RECKEYENTRY -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
  dictionary : () -> %
- dictionary : List Record(key: Key,entry: Entry) -> %
+ dictionary : List RECKEYENTRY -> %
  empty : () -> %                      
  empty? : % -> Boolean
  eq? : (%,%) -> Boolean
- eval : (%,List Record(key: Key,entry: Entry),List Record(key: Key,entry: 
Entry)) -> % if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: 
Entry) and Record(key: Key,entry: Entry) has SETCAT
- eval : (%,Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> % 
if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and 
Record(key: Key,entry: Entry) has SETCAT
- eval : (%,Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- eval : (%,List Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- every? : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Boolean if $ has 
finiteAggregate
+ eval : (%,List RECKEYENTRY,List RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,RECKEYENTRY,RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,List Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ every? : ((RECKEYENTRY -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
  key? : (Key,%) -> Boolean            
  keys : % -> List Key
- hash : % -> SingleInteger if Entry has SETCAT or Record(key: Key,entry: 
Entry) has SETCAT
- latex : % -> String if Entry has SETCAT or Record(key: Key,entry: Entry) has 
SETCAT
+ hash : % -> SingleInteger 
+          if Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
+ latex : % -> String 
+          if Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
  less? : (%,NonNegativeInteger) -> Boolean
- member? : (Record(key: Key,entry: Entry),%) -> Boolean 
-     if Record(key: Key,entry: Entry) has SETCAT 
+ member? : (RECKEYENTRY,%) -> Boolean 
+     if RECKEYENTRY has SETCAT 
       and $ has finiteAggregate
- members : % -> List Record(key: Key,entry: Entry) if $ has finiteAggregate
+ members : % -> List RECKEYENTRY if $ has finiteAggregate
  more? : (%,NonNegativeInteger) -> Boolean
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%) -> Record(key: Key,entry: Entry) if $ has 
finiteAggregate
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%,Record(key: Key,entry: Entry)) -> Record(key: 
Key,entry: Entry) if $ has finiteAggregate
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%,Record(key: Key,entry: Entry),Record(key: 
Key,entry: Entry)) -> Record(key: Key,entry: Entry) if Record(key: Key,entry: 
Entry) has SETCAT and $ has finiteAggregate
- remove : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- remove : (Record(key: Key,entry: Entry),%) -> % if Record(key: Key,entry: 
Entry) has SETCAT and $ has finiteAggregate
- remove! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- remove! : (Record(key: Key,entry: Entry),%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % if Record(key: Key,entry: Entry) has SETCAT and $ 
has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY) -> RECKEYENTRY),%) -> RECKEYENTRY 
+          if $ has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY)->RECKEYENTRY),%,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY)->RECKEYENTRY),%,RECKEYENTRY,RECKEYENTRY)
+    -> RECKEYENTRY 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ remove : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ remove : (RECKEYENTRY,%) -> % 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ remove! : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ remove! : (RECKEYENTRY,%) -> % if $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
  sample : () -> %                     
  search : (Key,%) -> Union(Entry,"failed")
- select : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- select! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
+ select : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ select! : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
  #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?~=? : (%,%) -> Boolean if Entry has SETCAT or Record(key: Key,entry: Entry) 
has SETCAT
+ ?~=? : (%,%) -> Boolean 
+          if Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
 \end{verbatim}
 
 These exports come from IndexedAggregate(Key,Entry))\\
-where Key:SetCategory and Entry:SetCategory:
+where Key:SetCategory and Entry:SetCategory\\
+and RECKEYENTRY=Record(key: Key,entry: Entry):
 \begin{verbatim}
- count : (Record(key: Key,entry: Entry),%) -> NonNegativeInteger if 
Record(key: Key,entry: Entry) has SETCAT and $ has finiteAggregate
- entry? : (Entry,%) -> Boolean if $ has finiteAggregate and Entry has SETCAT
- eval : (%,List Equation Entry) -> % if Entry has EVALAB Entry and Entry has 
SETCAT
- eval : (%,Equation Entry) -> % if Entry has EVALAB Entry and Entry has SETCAT
- eval : (%,Entry,Entry) -> % if Entry has EVALAB Entry and Entry has SETCAT
- eval : (%,List Entry,List Entry) -> % if Entry has EVALAB Entry and Entry has 
SETCAT
+ count : (RECKEYENTRY,%) -> NonNegativeInteger 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ entry? : (Entry,%) -> Boolean 
+          if $ has finiteAggregate 
+          and Entry has SETCAT
+ eval : (%,List Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Entry,Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List Entry,List Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
  fill! : (%,Entry) -> % if $ has shallowlyMutable
  first : % -> Entry if Key has ORDSET
  map : ((Entry -> Entry),%) -> %      
  maxIndex : % -> Key if Key has ORDSET
- member? : (Entry,%) -> Boolean if Entry has SETCAT and $ has finiteAggregate
+ member? : (Entry,%) -> Boolean 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
  members : % -> List Entry if $ has finiteAggregate
  minIndex : % -> Key if Key has ORDSET
  qelt : (%,Key) -> Entry
@@ -7980,7 +8502,8 @@ TableAggregate(Key:SetCategory, Entry:SetCategory): 
Category ==
 --    z
 
    if % has finiteAggregate then
-     parts(t:%):List Record(key:Key,entry:Entry) == [[k, t.k] for k in keys t]
+     parts(t:%):List Record(key:Key,entry:Entry) ==
+         [[k, t.k] for k in keys t]
      parts(t:%):List Entry   == [t.k for k in keys t]
      entries(t:%):List Entry == parts(t)
 
@@ -7988,7 +8511,8 @@ TableAggregate(Key:SetCategory, Entry:SetCategory): 
Category ==
        eq?(s,t) => true
        #s ^= #t => false
        for k in keys s repeat
-        (e := search(k, t)) case "failed" or (e::Entry) ^= s.k => return false
+        (e := search(k, t)) _
+           case "failed" or (e::Entry) ^= s.k => return false
        true
 
      map(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%==
@@ -7997,7 +8521,7 @@ TableAggregate(Key:SetCategory, Entry:SetCategory): 
Category ==
         ke: Record(key:Key,entry:Entry) := f [k, t.k]
         z ke.key := ke.entry
        z
-     map_!(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%_
+     map_!(f:Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry),t:%):%_
       ==
        lke: List Record(key:Key,entry:Entry) := nil()
        for k in keys t repeat
@@ -8259,109 +8783,191 @@ These are directly exported but not implemented:
 \end{verbatim}
 
 These exports come from TableAggregate(Key, Entry)\\
-where Key:SetCategory and Entry:SetCategory 
+where Key:SetCategory and Entry:SetCategory\\
+and RECKEYENTRY = Record(key: Key,entry: Entry)
 \begin{verbatim}
- any? : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Boolean if $ has 
finiteAggregate
- any? : ((Entry -> Boolean),%) -> Boolean if $ has finiteAggregate
- any? : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Boolean if $ has 
finiteAggregate
- bag : List Record(key: Key,entry: Entry) -> %
- construct : List Record(key: Key,entry: Entry) -> %
- convert : % -> InputForm if Record(key: Key,entry: Entry) has KONVERT INFORM 
or Record(key: Key,entry: Entry) has KONVERT INFORM
+ any? : ((RECKEYENTRY -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ any? : ((Entry -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ any? : ((RECKEYENTRY -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ bag : List RECKEYENTRY -> %
+ construct : List RECKEYENTRY -> %
+ convert : % -> InputForm 
+          if RECKEYENTRY has KONVERT INFORM 
+          or RECKEYENTRY has KONVERT INFORM
  copy : % -> %                        
- count : ((Record(key: Key,entry: Entry) -> Boolean),%) -> NonNegativeInteger 
if $ has finiteAggregate
- count : (Record(key: Key,entry: Entry),%) -> NonNegativeInteger if 
Record(key: Key,entry: Entry) has SETCAT and $ has finiteAggregate
- count : ((Entry -> Boolean),%) -> NonNegativeInteger if $ has finiteAggregate
- count : (Entry,%) -> NonNegativeInteger if Entry has SETCAT and $ has 
finiteAggregate
- count : (Record(key: Key,entry: Entry),%) -> NonNegativeInteger if 
Record(key: Key,entry: Entry) has SETCAT and $ has finiteAggregate
- count : ((Record(key: Key,entry: Entry) -> Boolean),%) -> NonNegativeInteger 
if $ has finiteAggregate
+ count : 
+  ((RECKEYENTRY -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ count : (RECKEYENTRY,%) -> NonNegativeInteger 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ count : ((Entry -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
+ count : (Entry,%) -> NonNegativeInteger 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ count : (RECKEYENTRY,%) -> NonNegativeInteger 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ count : 
+  ((RECKEYENTRY -> Boolean),%) -> NonNegativeInteger 
+          if $ has finiteAggregate
  dictionary : () -> %                 
- dictionary : List Record(key: Key,entry: Entry) -> %
+ dictionary : List RECKEYENTRY -> %
  elt : (%,Key,Entry) -> Entry
- elt : (%,Integer,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry)
+ elt : (%,Integer,RECKEYENTRY) -> RECKEYENTRY
  empty : () -> %
  empty? : % -> Boolean                
  entries : % -> List Entry
- entry? : (Entry,%) -> Boolean if $ has finiteAggregate and Entry has SETCAT
+ entry? : (Entry,%) -> Boolean 
+          if $ has finiteAggregate 
+          and Entry has SETCAT
  eq? : (%,%) -> Boolean               
- eval : (%,List Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- eval : (%,Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- eval : (%,Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> % 
if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and 
Record(key: Key,entry: Entry) has SETCAT
- eval : (%,List Record(key: Key,entry: Entry),List Record(key: Key,entry: 
Entry)) -> % if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: 
Entry) and Record(key: Key,entry: Entry) has SETCAT
- eval : (%,List Equation Entry) -> % if Entry has EVALAB Entry and Entry has 
SETCAT
- eval : (%,Equation Entry) -> % if Entry has EVALAB Entry and Entry has SETCAT
- eval : (%,Entry,Entry) -> % if Entry has EVALAB Entry and Entry has SETCAT
- eval : (%,List Entry,List Entry) -> % if Entry has EVALAB Entry and Entry has 
SETCAT
- eval : (%,List Record(key: Key,entry: Entry),List Record(key: Key,entry: 
Entry)) -> % if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: 
Entry) and Record(key: Key,entry: Entry) has SETCAT
- eval : (%,Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> % 
if Record(key: Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and 
Record(key: Key,entry: Entry) has SETCAT
- eval : (%,Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- eval : (%,List Equation Record(key: Key,entry: Entry)) -> % if Record(key: 
Key,entry: Entry) has EVALAB Record(key: Key,entry: Entry) and Record(key: 
Key,entry: Entry) has SETCAT
- every? : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Boolean if $ has 
finiteAggregate
- every? : ((Entry -> Boolean),%) -> Boolean if $ has finiteAggregate
- extract! : % -> Record(key: Key,entry: Entry)
+ eval : (%,List Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,RECKEYENTRY,RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,List RECKEYENTRY,List RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,List Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Equation Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,Entry,Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List Entry,List Entry) -> % 
+          if Entry has EVALAB Entry 
+          and Entry has SETCAT
+ eval : (%,List RECKEYENTRY,List RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,RECKEYENTRY,RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ eval : (%,List Equation RECKEYENTRY) -> % 
+          if RECKEYENTRY has EVALAB RECKEYENTRY 
+          and RECKEYENTRY has SETCAT
+ every? : ((RECKEYENTRY -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ every? : ((Entry -> Boolean),%) -> Boolean 
+          if $ has finiteAggregate
+ extract! : % -> RECKEYENTRY
  fill! : (%,Entry) -> % if $ has shallowlyMutable
- find : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Union(Record(key: 
Key,entry: Entry),"failed")
+ find : ((RECKEYENTRY -> Boolean),%) -> Union(RECKEYENTRY,"failed")
  first : % -> Entry if Key has ORDSET
- hash : % -> SingleInteger if Record(key: Key,entry: Entry) has SETCAT or 
Entry has SETCAT or Record(key: Key,entry: Entry) has SETCAT
+ hash : % -> SingleInteger 
+          if RECKEYENTRY has SETCAT 
+          or Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
  index? : (Key,%) -> Boolean
  indices : % -> List Key
- insert! : (Record(key: Key,entry: Entry),%) -> %
- inspect : % -> Record(key: Key,entry: Entry)
+ insert! : (RECKEYENTRY,%) -> %
+ inspect : % -> RECKEYENTRY
  key? : (Key,%) -> Boolean            
  keys : % -> List Key
- latex : % -> String if Record(key: Key,entry: Entry) has SETCAT or Entry has 
SETCAT or Record(key: Key,entry: Entry) has SETCAT
+ latex : % -> String 
+          if RECKEYENTRY has SETCAT 
+          or Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
  less? : (%,NonNegativeInteger) -> Boolean
  map : ((Entry -> Entry),%) -> %
- map : ((Record(key: Key,entry: Entry) -> Record(key: Key,entry: Entry)),%) -> 
%
+ map : ((RECKEYENTRY -> RECKEYENTRY),%) -> %
  map : (((Entry,Entry) -> Entry),%,%) -> %
- map! : ((Record(key: Key,entry: Entry) -> Record(key: Key,entry: Entry)),%) 
-> % if $ has shallowlyMutable
+ map! : ((RECKEYENTRY -> RECKEYENTRY),%) -> % 
+          if $ has shallowlyMutable
  map! : ((Entry -> Entry),%) -> % if $ has shallowlyMutable
- map! : ((Record(key: Key,entry: Entry) -> Record(key: Key,entry: Entry)),%) 
-> % if $ has shallowlyMutable
+ map! : ((RECKEYENTRY -> RECKEYENTRY),%) -> % 
+          if $ has shallowlyMutable
  maxIndex : % -> Key if Key has ORDSET
- member? : (Record(key: Key,entry: Entry),%) -> Boolean if Record(key: 
Key,entry: Entry) has SETCAT and $ has finiteAggregate
- member? : (Entry,%) -> Boolean if Entry has SETCAT and $ has finiteAggregate
- members : % -> List Record(key: Key,entry: Entry) if $ has finiteAggregate
+ member? : (RECKEYENTRY,%) -> Boolean 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ member? : (Entry,%) -> Boolean 
+          if Entry has SETCAT 
+          and $ has finiteAggregate
+ members : % -> List RECKEYENTRY if $ has finiteAggregate
  members : % -> List Entry if $ has finiteAggregate
- members : % -> List Record(key: Key,entry: Entry) if $ has finiteAggregate
+ members : % -> List RECKEYENTRY if $ has finiteAggregate
  minIndex : % -> Key if Key has ORDSET
  more? : (%,NonNegativeInteger) -> Boolean
  parts : % -> List Entry if $ has finiteAggregate
- parts : % -> List Record(key: Key,entry: Entry) if $ has finiteAggregate
+ parts : % -> List RECKEYENTRY if $ has finiteAggregate
  qelt : (%,Key) -> Entry              
  qsetelt! : (%,Key,Entry) -> Entry if $ has shallowlyMutable
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%) -> Record(key: Key,entry: Entry) if $ has 
finiteAggregate
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%,Record(key: Key,entry: Entry)) -> Record(key: 
Key,entry: Entry) if $ has finiteAggregate
- reduce : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%,Record(key: Key,entry: Entry),Record(key: 
Key,entry: Entry)) -> Record(key: Key,entry: Entry) if Record(key: Key,entry: 
Entry) has SETCAT and $ has finiteAggregate
- remove : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- remove : (Record(key: Key,entry: Entry),%) -> % if Record(key: Key,entry: 
Entry) has SETCAT and $ has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY) -> RECKEYENTRY),%)
+    -> RECKEYENTRY 
+          if $ has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY) -> RECKEYENTRY),%,RECKEYENTRY)
+    -> RECKEYENTRY 
+          if $ has finiteAggregate
+ reduce : 
+  (((RECKEYENTRY,RECKEYENTRY) -> RECKEYENTRY),%,RECKEYENTRY,RECKEYENTRY)
+    -> RECKEYENTRY 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
+ remove : ((RECKEYENTRY -> Boolean),%) -> % if $ has finiteAggregate
+ remove : (RECKEYENTRY,%) -> % 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
  remove! : (Key,%) -> Union(Entry,"failed")
- remove! : (Record(key: Key,entry: Entry),%) -> % if Record(key: Key,entry: 
Entry) has SETCAT
- remove! : (Record(key: Key,entry: Entry),%) -> % if $ has finiteAggregate
- removeDuplicates : % -> % if Record(key: Key,entry: Entry) has SETCAT and $ 
has finiteAggregate or Record(key: Key,entry: Entry) has SETCAT and $ has 
finiteAggregate
+ remove! : (RECKEYENTRY,%) -> % if RECKEYENTRY has SETCAT
+ remove! : (RECKEYENTRY,%) -> % if $ has finiteAggregate
+ removeDuplicates : % -> % 
+          if RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate 
+          or RECKEYENTRY has SETCAT 
+          and $ has finiteAggregate
  sample : () -> %
  search : (Key,%) -> Union(Entry,"failed")
- select : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- select! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
+ select : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ select! : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
  setelt : (%,Key,Entry) -> Entry      
  size? : (%,NonNegativeInteger) -> Boolean
  swap! : (%,Key,Key) -> Void if $ has shallowlyMutable
  table : () -> %
- table : List Record(key: Key,entry: Entry) -> %
- ?~=? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has SETCAT or Entry 
has SETCAT or Record(key: Key,entry: Entry) has SETCAT
+ table : List RECKEYENTRY -> %
+ ?~=? : (%,%) -> Boolean 
+          if RECKEYENTRY has SETCAT 
+          or Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
  ?.? : (%,Key) -> Entry               
 \end{verbatim}
 
 These exports come from ListAggregate(a:Type)\\
-where a is  Record(key:Key,entry:Entry)
+where a is  Record(key:Key,entry:Entry)\\
+and RECKEYENTRY=Record(key: Key,entry: Entry)
 \begin{verbatim}
  children : % -> List %               
- child? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has SETCAT
- coerce : % -> OutputForm if Record(key: Key,entry: Entry) has SETCAT or Entry 
has SETCAT or Record(key: Key,entry: Entry) has SETCAT
+ child? : (%,%) -> Boolean if RECKEYENTRY has SETCAT
+ coerce : % -> OutputForm 
+          if RECKEYENTRY has SETCAT 
+          or Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
  concat : (%,%) -> %
  concat : List % -> %                 
- concat : (Record(key: Key,entry: Entry),%) -> %
- concat : (%,Record(key: Key,entry: Entry)) -> %
+ concat : (RECKEYENTRY,%) -> %
+ concat : (%,RECKEYENTRY) -> %
  concat! : (%,%) -> %
- concat! : (%,Record(key: Key,entry: Entry)) -> %
+ concat! : (%,RECKEYENTRY) -> %
  copyInto! : (%,%,Integer) -> % if $ has shallowlyMutable
  cycleEntry : % -> %
  cycleLength : % -> NonNegativeInteger
@@ -8373,84 +8979,105 @@ where a is  Record(key:Key,entry:Entry)
  delete : (%,UniversalSegment Integer) -> %
  delete! : (%,UniversalSegment Integer) -> %
  distance : (%,%) -> Integer
- entries : % -> List Record(key: Key,entry: Entry)
- entry? : (Record(key: Key,entry: Entry),%) -> Boolean if $ has 
finiteAggregate and Record(key: Key,entry: Entry) has SETCAT
+ entries : % -> List RECKEYENTRY
+ entry? : (RECKEYENTRY,%) -> Boolean 
+          if $ has finiteAggregate 
+          and RECKEYENTRY has SETCAT
  explicitlyFinite? : % -> Boolean
- fill! : (%,Record(key: Key,entry: Entry)) -> % if $ has shallowlyMutable
- first : % -> Record(key: Key,entry: Entry)
+ fill! : (%,RECKEYENTRY) -> % if $ has shallowlyMutable
+ first : % -> RECKEYENTRY
  first : (%,NonNegativeInteger) -> %
  index? : (Integer,%) -> Boolean      
  indices : % -> List Integer          
  insert : (%,%,Integer) -> %          
- insert : (Record(key: Key,entry: Entry),%,Integer) -> %
+ insert : (RECKEYENTRY,%,Integer) -> %
  insert! : (%,%,Integer) -> %
- insert! : (Record(key: Key,entry: Entry),%,Integer) -> %
- last : % -> Record(key: Key,entry: Entry)
+ insert! : (RECKEYENTRY,%,Integer) -> %
+ last : % -> RECKEYENTRY
  last : (%,NonNegativeInteger) -> %
  leaf? : % -> Boolean                 
- leaves : % -> List Record(key: Key,entry: Entry)
- list : Record(key: Key,entry: Entry) -> %
- map : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry)),%,%) -> %
- max : (%,%) -> % if Record(key: Key,entry: Entry) has ORDSET
+ leaves : % -> List RECKEYENTRY
+ list : RECKEYENTRY -> %
+ map : (((RECKEYENTRY,RECKEYENTRY) -> RECKEYENTRY),%,%) -> %
+ max : (%,%) -> % if RECKEYENTRY has ORDSET
  maxIndex : % -> Integer if Integer has ORDSET
- merge : (%,%) -> % if Record(key: Key,entry: Entry) has ORDSET
- merge : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Boolean),%,%) -> %
- merge! : (%,%) -> % if Record(key: Key,entry: Entry) has ORDSET
- merge! : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Boolean),%,%) -> %
- min : (%,%) -> % if Record(key: Key,entry: Entry) has ORDSET
+ merge : (%,%) -> % if RECKEYENTRY has ORDSET
+ merge : (((RECKEYENTRY,RECKEYENTRY) -> Boolean),%,%) -> %
+ merge! : (%,%) -> % if RECKEYENTRY has ORDSET
+ merge! : (((RECKEYENTRY,RECKEYENTRY) -> Boolean),%,%) -> %
+ min : (%,%) -> % if RECKEYENTRY has ORDSET
  minIndex : % -> Integer if Integer has ORDSET
- new : (NonNegativeInteger,Record(key: Key,entry: Entry)) -> %
+ new : (NonNegativeInteger,RECKEYENTRY) -> %
  nodes : % -> List %                  
- node? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has SETCAT
- position : (Record(key: Key,entry: Entry),%,Integer) -> Integer if 
Record(key: Key,entry: Entry) has SETCAT
- position : (Record(key: Key,entry: Entry),%) -> Integer if Record(key: 
Key,entry: Entry) has SETCAT
- position : ((Record(key: Key,entry: Entry) -> Boolean),%) -> Integer
+ node? : (%,%) -> Boolean if RECKEYENTRY has SETCAT
+ position : (RECKEYENTRY,%,Integer) -> Integer 
+          if RECKEYENTRY has SETCAT
+ position : (RECKEYENTRY,%) -> Integer 
+          if RECKEYENTRY has SETCAT
+ position : ((RECKEYENTRY -> Boolean),%) -> Integer
  possiblyInfinite? : % -> Boolean
- qelt : (%,Integer) -> Record(key: Key,entry: Entry)
- qsetelt! : (%,Integer,Record(key: Key,entry: Entry)) -> Record(key: 
Key,entry: Entry) if $ has shallowlyMutable
- remove! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> %
- remove! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> % if $ has 
finiteAggregate
- removeDuplicates! : % -> % if Record(key: Key,entry: Entry) has SETCAT
+ qelt : (%,Integer) -> RECKEYENTRY
+ qsetelt! : (%,Integer,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ remove! : ((RECKEYENTRY -> Boolean),%) -> %
+ remove! : ((RECKEYENTRY -> Boolean),%) -> % 
+          if $ has finiteAggregate
+ removeDuplicates! : % -> % if RECKEYENTRY has SETCAT
  rest : % -> %
  rest : (%,NonNegativeInteger) -> %
  reverse : % -> %                     
  reverse! : % -> % if $ has shallowlyMutable
- second : % -> Record(key: Key,entry: Entry)
- select! : ((Record(key: Key,entry: Entry) -> Boolean),%) -> %
+ second : % -> RECKEYENTRY
+ select! : ((RECKEYENTRY -> Boolean),%) -> %
  setchildren! : (%,List %) -> % if $ has shallowlyMutable
- setelt : (%,value,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
- setelt : (%,first,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
+ setelt : (%,value,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ setelt : (%,first,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
  setelt : (%,rest,%) -> % if $ has shallowlyMutable
- setelt : (%,last,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
- setelt : (%,UniversalSegment Integer,Record(key: Key,entry: Entry)) -> 
Record(key: Key,entry: Entry) if $ has shallowlyMutable
- setelt : (%,Integer,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
- setfirst! : (%,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
- setlast! : (%,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: Entry) 
if $ has shallowlyMutable
+ setelt : (%,last,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ setelt : (%,UniversalSegment Integer,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ setelt : (%,Integer,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ setfirst! : (%,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ setlast! : (%,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
  setrest! : (%,%) -> % if $ has shallowlyMutable
- setvalue! : (%,Record(key: Key,entry: Entry)) -> Record(key: Key,entry: 
Entry) if $ has shallowlyMutable
- sort : % -> % if Record(key: Key,entry: Entry) has ORDSET
- sort : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Boolean),%) -> %
- sort! : % -> % if Record(key: Key,entry: Entry) has ORDSET and $ has 
shallowlyMutable
- sort! : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Boolean),%) -> % if $ has shallowlyMutable
- sorted? : % -> Boolean if Record(key: Key,entry: Entry) has ORDSET
- sorted? : (((Record(key: Key,entry: Entry),Record(key: Key,entry: Entry)) -> 
Boolean),%) -> Boolean
+ setvalue! : (%,RECKEYENTRY) -> RECKEYENTRY 
+          if $ has shallowlyMutable
+ sort : % -> % if RECKEYENTRY has ORDSET
+ sort : (((RECKEYENTRY,RECKEYENTRY) -> Boolean),%) -> %
+ sort! : % -> % 
+          if RECKEYENTRY has ORDSET 
+          and $ has shallowlyMutable
+ sort! : (((RECKEYENTRY,RECKEYENTRY) -> Boolean),%) -> % 
+          if $ has shallowlyMutable
+ sorted? : % -> Boolean if RECKEYENTRY has ORDSET
+ sorted? : (((RECKEYENTRY,RECKEYENTRY) -> Boolean),%) -> Boolean
  split! : (%,Integer) -> % if $ has shallowlyMutable
- swap! : (%,Integer,Integer) -> Void if $ has shallowlyMutable
+ swap! : (%,Integer,Integer) -> Void 
+          if $ has shallowlyMutable
  tail : % -> %                        
- third : % -> Record(key: Key,entry: Entry)
- value : % -> Record(key: Key,entry: Entry)
+ third : % -> RECKEYENTRY
+ value : % -> RECKEYENTRY
  #? : % -> NonNegativeInteger if $ has finiteAggregate
- ?<? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has ORDSET
- ?<=? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has ORDSET
- ?=? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has SETCAT or Entry 
has SETCAT or Record(key: Key,entry: Entry) has SETCAT
- ?>? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has ORDSET
- ?>=? : (%,%) -> Boolean if Record(key: Key,entry: Entry) has ORDSET
- ?.value : (%,value) -> Record(key: Key,entry: Entry)
- ?.first : (%,first) -> Record(key: Key,entry: Entry)
- ?.last : (%,last) -> Record(key: Key,entry: Entry)
+ ?<? : (%,%) -> Boolean if RECKEYENTRY has ORDSET
+ ?<=? : (%,%) -> Boolean if RECKEYENTRY has ORDSET
+ ?=? : (%,%) -> Boolean 
+          if RECKEYENTRY has SETCAT 
+          or Entry has SETCAT 
+          or RECKEYENTRY has SETCAT
+ ?>? : (%,%) -> Boolean if RECKEYENTRY has ORDSET
+ ?>=? : (%,%) -> Boolean if RECKEYENTRY has ORDSET
+ ?.value : (%,value) -> RECKEYENTRY
+ ?.first : (%,first) -> RECKEYENTRY
+ ?.last : (%,last) -> RECKEYENTRY
  ?.rest : (%,rest) -> %               
  ?.? : (%,UniversalSegment Integer) -> %
- ?.? : (%,Integer) -> Record(key: Key,entry: Entry)
+ ?.? : (%,Integer) -> RECKEYENTRY
 \end{verbatim}
 
 These exports come from SetCategory:
@@ -8473,7 +9100,8 @@ These exports come from SetCategory:
 ++ as a table. It is a poor mans version of a table:
 ++ searching for a key is a linear operation.
 AssociationListAggregate(Key:SetCategory,Entry:SetCategory): Category ==
-   Join(TableAggregate(Key, Entry), ListAggregate Record(key:Key,entry:Entry)) 
with
+   Join(TableAggregate(Key, Entry), _
+         ListAggregate Record(key:Key,entry:Entry)) with
       assoc: (Key, %) -> Union(Record(key:Key,entry:Entry), "failed")
        ++ assoc(k,u) returns the element x in association list u stored
        ++ with key k, or "failed" if u has no key k.
@@ -8616,7 +9244,8 @@ FiniteSetAggregate(S:SetCategory): Category ==
      size()  == 2 ** size()$S
      index i ==
        {index(j::PositiveInteger)$S for j in 1..size()$S | bit?(i-1,j-1)}
-     random()  == index((random()$Integer rem (size()$% + 1))::PositiveInteger)
+     random()  == 
+       index((random()$Integer rem (size()$% + 1))::PositiveInteger)
 
      lookup s ==
        n:PositiveInteger := 1
@@ -8671,17 +9300,17 @@ BitAggregate(): Category ==
       ++ ^ b returns the logical {\em not} of bit aggregate 
       ++ \axiom{b}.
     nand : (%, %) -> %
-      ++ nand(a,b) returns the logical {\em nand} of bit aggregates \axiom{a}
-      ++ and \axiom{b}.
+      ++ nand(a,b) returns the logical {\em nand} of bit aggregates 
+      ++ \axiom{a} and \axiom{b}.
     nor         : (%, %) -> %
-      ++ nor(a,b) returns the logical {\em nor} of bit aggregates \axiom{a} 
and 
-      ++ \axiom{b}.
+      ++ nor(a,b) returns the logical {\em nor} of bit aggregates 
+      ++ \axiom{a} and \axiom{b}.
     _and : (%, %) -> %
-      ++ a and b returns the logical {\em and} of bit aggregates \axiom{a} and 
-      ++ \axiom{b}.
+      ++ a and b returns the logical {\em and} of bit aggregates 
+      ++ \axiom{a} and \axiom{b}.
     _or         : (%, %) -> %
-      ++ a or b returns the logical {\em or} of bit aggregates \axiom{a} and 
-      ++ \axiom{b}.
+      ++ a or b returns the logical {\em or} of bit aggregates 
+      ++ \axiom{a} and \axiom{b}.
     xor         : (%, %) -> %
       ++ xor(a,b) returns the logical {\em exclusive-or} of bit aggregates
       ++ \axiom{a} and \axiom{b}.
@@ -8771,7 +9400,8 @@ OrderedMultisetAggregate(S:OrderedSet): Category ==
 
 @
 <<OMSAGG.dotabb>>=
-"OMSAGG" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=OMSAGG"];
+"OMSAGG"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=OMSAGG"];
 "OMSAGG" -> "MSETAGG"
 "OMSAGG" -> "PRQAGG"
 
@@ -8779,7 +9409,8 @@ OrderedMultisetAggregate(S:OrderedSet): Category ==
 <<OMSAGG.dotfull>>=
 "OrderedMultisetAggregate(a:SetCategory)"
  [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=OMSAGG"];
-"OrderedMultisetAggregate(a:SetCategory)" -> "MultisetAggregate(a:SetCategory)"
+"OrderedMultisetAggregate(a:SetCategory)" ->
+    "MultisetAggregate(a:SetCategory)"
 "OrderedMultisetAggregate(a:SetCategory)" -> 
    "PriorityQueueAggregate(a:SetCategory)"
 
@@ -8838,10 +9469,10 @@ SetAggregate(S:SetCategory):
      ++ If u does not contain x, a copy of u is returned.
      ++ Note: \axiom{difference(s, x) = difference(s, {x})}.
    symmetricDifference : (%, %) -> %
-     ++ symmetricDifference(u,v) returns the set aggregate of elements x which
-     ++ are members of set aggregate u or set aggregate v but not both.
-     ++ If u and v have no elements in common, \axiom{symmetricDifference(u,v)}
-     ++ returns a copy of u.
+     ++ symmetricDifference(u,v) returns the set aggregate of elements x 
+     ++ which are members of set aggregate u or set aggregate v but 
+     ++ not both. If u and v have no elements in common, 
+     ++ \axiom{symmetricDifference(u,v)} returns a copy of u.
      ++ Note: \axiom{symmetricDifference(u,v) = 
      ++  union(difference(u,v),difference(v,u))}
    subset?     : (%, %) -> Boolean
@@ -8865,7 +9496,8 @@ SetAggregate(S:SetCategory):
 
 @
 <<SETAGG.dotabb>>=
-"SETAGG" [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SETAGG"];
+"SETAGG"
+ [color=lightblue,href="books/bookvol10.2.pamphlet#nameddest=SETAGG"];
 "SETAGG" -> "SETCAT"
 "SETAGG" -> "CLAGG"
 
@@ -8885,13 +9517,6 @@ SetAggregate(S:SetCategory):
  [color="#00EE00",href="books/bookvol10.2.pamphlet#nameddest=EVALAB"];
 @
 
-\pagehead{OrderedSet}{ORDSET}
-\pageto{FiniteLinearAggregate}{FLAGG}
-<<ORDSET.dotfull>>=
-"OrderedSet"
- [color="#00EE00",href="books/bookvol10.2.pamphlet#nameddest=ORDSET"];
-@
-
 \chapter{The bootstrap code}
 \section{ABELSG.lsp BOOTSTRAP}
 {\bf ABELSG} needs
@@ -12396,6 +13021,7 @@ Note that this code is not included in the generated 
catdef.spad file.
 <<category ELAGG ExtensibleLinearAggregate>>
 <<category ELTAB Eltable>>
 <<category ELTAGG EltableAggregate>>
+<<category FINITE Finite>>
 <<category FLAGG FiniteLinearAggregate>>
 <<category FSAGG FiniteSetAggregate>>
 <<category HOAGG HomogeneousAggregate>>
@@ -12408,12 +13034,14 @@ Note that this code is not included in the generated 
catdef.spad file.
 <<category MDAGG MultiDictionary>>
 <<category MSETAGG MultisetAggregate>>
 <<category OMSAGG OrderedMultisetAggregate>>
+<<category ORDSET OrderedSet>>
 <<category PRQAGG PriorityQueueAggregate>>
 <<category QUAGG QueueAggregate>>
 <<category RCAGG RecursiveAggregate>>
 <<category RETRACT RetractableTo>>
 <<category SETAGG SetAggregate>>
 <<category SETCAT SetCategory>>
+<<category SGROUP SemiGroup>>
 <<category SKAGG StackAggregate>>
 <<category SRAGG StringAggregate>>
 <<category STAGG StreamAggregate>>
@@ -12446,6 +13074,7 @@ digraph dotabb {
 <<ELAGG.dotabb>>
 <<ELTAB.dotabb>>
 <<ELTAGG.dotabb>>
+<<FINITE.dotabb>>
 <<FLAGG.dotabb>>
 <<FSAGG.dotabb>>
 <<HOAGG.dotabb>>
@@ -12458,12 +13087,14 @@ digraph dotabb {
 <<MDAGG.dotabb>>
 <<MSETAGG.dotabb>>
 <<OMSAGG.dotabb>>
+<<ORDSET.dotabb>>
 <<PRQAGG.dotabb>>
 <<QUAGG.dotabb>>
 <<RCAGG.dotabb>>
 <<RETRACT.dotabb>>
 <<SETAGG.dotabb>>
 <<SETCAT.dotabb>>
+<<SGROUP.dotabb>>
 <<SKAGG.dotabb>>
 <<SRAGG.dotabb>>
 <<STAGG.dotabb>>
@@ -12499,6 +13130,7 @@ digraph dotfull {
 <<ELAGG.dotfull>>
 <<ELTAB.dotfull>>
 <<ELTAGG.dotfull>>
+<<FINITE.dotfull>>
 <<FLAGG.dotfull>>
 <<FSAGG.dotfull>>
 <<HOAGG.dotfull>>
@@ -12511,12 +13143,14 @@ digraph dotfull {
 <<MDAGG.dotfull>>
 <<MSETAGG.dotfull>>
 <<OMSAGG.dotfull>>
+<<ORDSET.dotfull>>
 <<PRQAGG.dotfull>>
 <<QUAGG.dotfull>>
 <<RCAGG.dotfull>>
 <<RETRACT.dotfull>>
 <<SETAGG.dotfull>>
 <<SETCAT.dotfull>>
+<<SGROUP.dotfull>>
 <<SKAGG.dotfull>>
 <<SRAGG.dotfull>>
 <<STAGG.dotfull>>
diff --git a/books/ps/v102finite.ps b/books/ps/v102finite.ps
new file mode 100644
index 0000000..c69cc5f
--- /dev/null
+++ b/books/ps/v102finite.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 290 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 290 368
+%%PageOrientation: Portrait
+gsave
+36 36 254 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
+252 330 lineto
+252 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+252 330 lineto
+252 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% Finite()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 134 324 moveto
+76 324 lineto
+76 288 lineto
+134 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 134 324 moveto
+76 324 lineto
+76 288 lineto
+134 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+84 301 moveto
+(Finite\(\))
+[7.44 3.84 6.96 3.84 3.84 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 152 252 moveto
+58 252 lineto
+58 216 lineto
+152 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 152 252 moveto
+58 252 lineto
+58 216 lineto
+152 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+65 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
+% Finite()->SetCategory()
+newpath 105 288 moveto
+105 280 105 271 105 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 109 262 moveto
+105 252 lineto
+102 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 109 262 moveto
+105 252 lineto
+102 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 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 93 216 moveto
+86 206 78 192 73 180 curveto
+64 160 55 136 50 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 53 117 moveto
+47 108 lineto
+47 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 53 117 moveto
+47 108 lineto
+47 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 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 120 216 moveto
+127 207 135 197 143 188 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 146 190 moveto
+149 180 lineto
+140 186 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 146 190 moveto
+149 180 lineto
+140 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 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/v102homogeneousaggregate.ps 
b/books/ps/v102homogeneousaggregate.ps
index da1413b..a142482 100644
--- a/books/ps/v102homogeneousaggregate.ps
+++ b/books/ps/v102homogeneousaggregate.ps
@@ -3,7 +3,7 @@
 %%For: (root) root
 %%Title: pic
 %%Pages: (atend)
-%%BoundingBox: 36 36 362 296
+%%BoundingBox: 36 36 405 368
 %%EndComments
 save
 %%BeginProlog
@@ -180,10 +180,10 @@ def
 
 %%EndSetup
 %%Page: 1 1
-%%PageBoundingBox: 36 36 362 296
+%%PageBoundingBox: 36 36 405 368
 %%PageOrientation: Portrait
 gsave
-36 36 326 260 boxprim clip newpath
+36 36 369 332 boxprim clip newpath
 36 36 translate
 0 0 1 beginpage
 1.0000 set_scale
@@ -191,303 +191,451 @@ gsave
 0.167 0.600 1.000 graphcolor
 0.167 0.600 1.000 graphcolor
 newpath -6 -6 moveto
--6 258 lineto
-324 258 lineto
-324 -6 lineto
+-6 330 lineto
+367 330 lineto
+367 -6 lineto
 closepath
 fill
 0.167 0.600 1.000 graphcolor
 newpath -6 -6 moveto
--6 258 lineto
-324 258 lineto
-324 -6 lineto
+-6 330 lineto
+367 330 lineto
+367 -6 lineto
 closepath
 stroke
 0.000 0.000 0.000 graphcolor
 14.00 /Times-Roman set_font
 % HomogeneousAggregate(a:Type)
-[ /Rect [ 57 216 259 252 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.2.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
 0.537 0.247 0.902 nodecolor
-newpath 259 252 moveto
-57 252 lineto
-57 216 lineto
-259 216 lineto
+newpath 259 324 moveto
+57 324 lineto
+57 288 lineto
+259 288 lineto
 closepath
 fill
 0.537 0.247 0.902 nodecolor
-newpath 259 252 moveto
-57 252 lineto
-57 216 lineto
-259 216 lineto
+newpath 259 324 moveto
+57 324 lineto
+57 288 lineto
+259 288 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-64 229 moveto
+64 301 moveto
 (HomogeneousAggregate\(a:Type\))
 [10.08 6.96 10.8 6.96 6.72 6.24 6.96 6.24 6.96 6.96 5.52 9.84 6.96 7.2 4.8 
6.24 6.72 6.24 3.84 6.24 4.56 6.24 3.84 7.2 6.96 6.96 6.24 4.56]
 xshow
 end grestore
 end grestore
 % Aggregate()
-[ /Rect [ 0 144 84 180 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.2.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
 0.537 0.247 0.902 nodecolor
-newpath 84 180 moveto
-0 180 lineto
-0 144 lineto
-84 144 lineto
+newpath 84 252 moveto
+0 252 lineto
+0 216 lineto
+84 216 lineto
 closepath
 fill
 0.537 0.247 0.902 nodecolor
-newpath 84 180 moveto
-0 180 lineto
-0 144 lineto
-84 144 lineto
+newpath 84 252 moveto
+0 252 lineto
+0 216 lineto
+84 216 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-7 157 moveto
+7 229 moveto
 (Aggregate\(\))
 [9.84 6.96 7.2 4.8 6.24 6.72 6.24 3.84 6.24 4.56 4.56]
 xshow
 end grestore
 end grestore
 % HomogeneousAggregate(a:Type)->Aggregate()
-newpath 129 216 moveto
-114 207 95 196 80 186 curveto
+newpath 129 288 moveto
+114 279 95 268 80 258 curveto
 stroke
 gsave 10 dict begin
 solid
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 81 183 moveto
-71 180 lineto
-77 188 lineto
+newpath 81 255 moveto
+71 252 lineto
+77 260 lineto
 closepath
 fill
 0.000 0.000 0.000 edgecolor
-newpath 81 183 moveto
-71 180 lineto
-77 188 lineto
+newpath 81 255 moveto
+71 252 lineto
+77 260 lineto
 closepath
 stroke
 end grestore
 % Evalable(a:Type)
-[ /Rect [ 102 144 214 180 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.333 1.000 0.933 nodecolor
 0.333 1.000 0.933 nodecolor
-newpath 214 180 moveto
-102 180 lineto
-102 144 lineto
-214 144 lineto
+newpath 214 252 moveto
+102 252 lineto
+102 216 lineto
+214 216 lineto
 closepath
 fill
 0.333 1.000 0.933 nodecolor
-newpath 214 180 moveto
-102 180 lineto
-102 144 lineto
-214 144 lineto
+newpath 214 252 moveto
+102 252 lineto
+102 216 lineto
+214 216 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-110 157 moveto
+110 229 moveto
 (Evalable\(a:Type\))
 [8.64 6.72 6.24 3.84 6.24 6.96 3.84 6.24 4.56 6.24 3.84 7.2 6.96 6.96 6.24 
4.56]
 xshow
 end grestore
 end grestore
 % HomogeneousAggregate(a:Type)->Evalable(a:Type)
-newpath 158 216 moveto
-158 208 158 199 158 190 curveto
+newpath 158 288 moveto
+158 280 158 271 158 262 curveto
 stroke
 gsave 10 dict begin
 solid
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 162 190 moveto
-158 180 lineto
-155 190 lineto
+newpath 162 262 moveto
+158 252 lineto
+155 262 lineto
 closepath
 fill
 0.000 0.000 0.000 edgecolor
-newpath 162 190 moveto
-158 180 lineto
-155 190 lineto
+newpath 162 262 moveto
+158 252 lineto
+155 262 lineto
 closepath
 stroke
 end grestore
-% SetCategory
-[ /Rect [ 232 144 318 180 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
+% SetCategory()
 gsave 10 dict begin
 filled
-0.333 1.000 0.933 nodecolor
-0.333 1.000 0.933 nodecolor
-newpath 318 180 moveto
-232 180 lineto
-232 144 lineto
-318 144 lineto
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 326 252 moveto
+232 252 lineto
+232 216 lineto
+326 216 lineto
 closepath
 fill
-0.333 1.000 0.933 nodecolor
-newpath 318 180 moveto
-232 180 lineto
-232 144 lineto
-318 144 lineto
+0.537 0.247 0.902 nodecolor
+newpath 326 252 moveto
+232 252 lineto
+232 216 lineto
+326 216 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-240 157 moveto
-(SetCategory)
-[7.68 6 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96]
+239 229 moveto
+(SetCategory\(\))
+[7.68 6 3.84 9.36 6.24 3.84 6.24 6.96 6.96 5.04 6.96 4.56 4.56]
 xshow
 end grestore
 end grestore
-% HomogeneousAggregate(a:Type)->SetCategory
-newpath 188 216 moveto
-203 207 221 195 237 185 curveto
+% HomogeneousAggregate(a:Type)->SetCategory()
+newpath 189 288 moveto
+204 279 223 267 240 257 curveto
 stroke
 gsave 10 dict begin
 solid
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 239 188 moveto
-246 180 lineto
-236 182 lineto
+newpath 242 260 moveto
+249 252 lineto
+239 254 lineto
 closepath
 fill
 0.000 0.000 0.000 edgecolor
-newpath 239 188 moveto
-246 180 lineto
-236 182 lineto
+newpath 242 260 moveto
+249 252 lineto
+239 254 lineto
 closepath
 stroke
 end grestore
 % Type()
-[ /Rect [ 15 72 69 108 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.2.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
 0.537 0.247 0.902 nodecolor
-newpath 69 108 moveto
-15 108 lineto
-15 72 lineto
-69 72 lineto
+newpath 99 108 moveto
+45 108 lineto
+45 72 lineto
+99 72 lineto
 closepath
 fill
 0.537 0.247 0.902 nodecolor
-newpath 69 108 moveto
-15 108 lineto
-15 72 lineto
-69 72 lineto
+newpath 99 108 moveto
+45 108 lineto
+45 72 lineto
+99 72 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-23 85 moveto
+53 85 moveto
 (Type\(\))
 [7.2 6.96 6.96 6.24 4.56 4.56]
 xshow
 end grestore
 end grestore
 % Aggregate()->Type()
-newpath 42 144 moveto
-42 136 42 127 42 118 curveto
+newpath 46 216 moveto
+51 191 61 147 66 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 69 118 moveto
+68 108 lineto
+63 117 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 69 118 moveto
+68 108 lineto
+63 117 lineto
+closepath
+stroke
+end grestore
+% BasicType()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 179 180 moveto
+95 180 lineto
+95 144 lineto
+179 144 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 179 180 moveto
+95 180 lineto
+95 144 lineto
+179 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+102 157 moveto
+(BasicType\(\))
+[9.36 6.24 5.52 3.84 6.24 7.2 6.96 6.96 6.24 4.56 4.56]
+xshow
+end grestore
+end grestore
+% SetCategory()->BasicType()
+newpath 243 216 moveto
+224 206 201 195 181 185 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 182 182 moveto
+172 180 lineto
+179 188 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 182 182 moveto
+172 180 lineto
+179 188 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(OutputForm)
+gsave 10 dict begin
+filled
+0.404 0.667 0.545 nodecolor
+0.404 0.667 0.545 nodecolor
+newpath 361 180 moveto
+197 180 lineto
+197 144 lineto
+361 144 lineto
+closepath
+fill
+0.404 0.667 0.545 nodecolor
+newpath 361 180 moveto
+197 180 lineto
+197 144 lineto
+361 144 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+205 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 279 216 moveto
+279 208 279 199 279 190 curveto
 stroke
 gsave 10 dict begin
 solid
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 46 118 moveto
-42 108 lineto
-39 118 lineto
+newpath 283 190 moveto
+279 180 lineto
+276 190 lineto
 closepath
 fill
 0.000 0.000 0.000 edgecolor
-newpath 46 118 moveto
-42 108 lineto
-39 118 lineto
+newpath 283 190 moveto
+279 180 lineto
+276 190 lineto
 closepath
 stroke
 end grestore
 % Category
-[ /Rect [ 8 0 76 36 ]
-  /Border [ 0 0 0 ]
-  /Action << /Subtype /URI /URI (books/bookvol10.pamphlet) >>
-  /Subtype /Link
-/ANN pdfmark
 gsave 10 dict begin
 filled
 0.537 0.247 0.902 nodecolor
 0.537 0.247 0.902 nodecolor
-newpath 76 36 moveto
-8 36 lineto
-8 0 lineto
-76 0 lineto
+newpath 171 36 moveto
+103 36 lineto
+103 0 lineto
+171 0 lineto
 closepath
 fill
 0.537 0.247 0.902 nodecolor
-newpath 76 36 moveto
-8 36 lineto
-8 0 lineto
-76 0 lineto
+newpath 171 36 moveto
+103 36 lineto
+103 0 lineto
+171 0 lineto
 closepath
 stroke
 gsave 10 dict begin
 0.000 0.000 0.000 nodecolor
-16 13 moveto
+111 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 137 144 moveto
+137 119 137 75 137 46 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 141 46 moveto
+137 36 lineto
+134 46 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 141 46 moveto
+137 36 lineto
+134 46 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 321 108 moveto
+189 108 lineto
+189 72 lineto
+321 72 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 321 108 moveto
+189 108 lineto
+189 72 lineto
+321 72 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+197 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 273 144 moveto
+270 136 267 126 264 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 267 117 moveto
+261 108 lineto
+261 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 267 117 moveto
+261 108 lineto
+261 119 lineto
+closepath
+stroke
+end grestore
+% CoercibleTo(a:Type)->Category
+newpath 225 72 moveto
+210 63 191 51 175 41 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 176 38 moveto
+166 36 lineto
+173 44 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 176 38 moveto
+166 36 lineto
+173 44 lineto
+closepath
+stroke
+end grestore
 % Type()->Category
-newpath 42 72 moveto
-42 64 42 55 42 46 curveto
+newpath 88 72 moveto
+96 63 105 53 114 44 curveto
 stroke
 gsave 10 dict begin
 solid
 1 setlinewidth
 0.000 0.000 0.000 edgecolor
-newpath 46 46 moveto
-42 36 lineto
-39 46 lineto
+newpath 117 46 moveto
+121 36 lineto
+112 41 lineto
 closepath
 fill
 0.000 0.000 0.000 edgecolor
-newpath 46 46 moveto
-42 36 lineto
-39 46 lineto
+newpath 117 46 moveto
+121 36 lineto
+112 41 lineto
 closepath
 stroke
 end grestore
diff --git a/books/ps/v102orderedset.ps b/books/ps/v102orderedset.ps
new file mode 100644
index 0000000..70e3654
--- /dev/null
+++ b/books/ps/v102orderedset.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 290 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 290 368
+%%PageOrientation: Portrait
+gsave
+36 36 254 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
+252 330 lineto
+252 -6 lineto
+closepath
+fill
+0.167 0.600 1.000 graphcolor
+newpath -6 -6 moveto
+-6 330 lineto
+252 330 lineto
+252 -6 lineto
+closepath
+stroke
+0.000 0.000 0.000 graphcolor
+14.00 /Times-Roman set_font
+% OrderedSet()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 149 324 moveto
+61 324 lineto
+61 288 lineto
+149 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 149 324 moveto
+61 324 lineto
+61 288 lineto
+149 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+68 301 moveto
+(OrderedSet\(\))
+[10.08 4.56 6.96 6.24 4.8 6.24 6.96 7.68 6 3.84 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 152 252 moveto
+58 252 lineto
+58 216 lineto
+152 216 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 152 252 moveto
+58 252 lineto
+58 216 lineto
+152 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+65 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
+% OrderedSet()->SetCategory()
+newpath 105 288 moveto
+105 280 105 271 105 262 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 109 262 moveto
+105 252 lineto
+102 262 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 109 262 moveto
+105 252 lineto
+102 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 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 93 216 moveto
+86 206 78 192 73 180 curveto
+64 160 55 136 50 118 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 53 117 moveto
+47 108 lineto
+47 119 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 53 117 moveto
+47 108 lineto
+47 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 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 120 216 moveto
+127 207 135 197 143 188 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 146 190 moveto
+149 180 lineto
+140 186 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 146 190 moveto
+149 180 lineto
+140 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 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/v102semigroup.ps b/books/ps/v102semigroup.ps
new file mode 100644
index 0000000..eded6fb
--- /dev/null
+++ b/books/ps/v102semigroup.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
+% SemiGroup()
+gsave 10 dict begin
+filled
+0.537 0.247 0.902 nodecolor
+0.537 0.247 0.902 nodecolor
+newpath 300 324 moveto
+210 324 lineto
+210 288 lineto
+300 288 lineto
+closepath
+fill
+0.537 0.247 0.902 nodecolor
+newpath 300 324 moveto
+210 324 lineto
+210 288 lineto
+300 288 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+218 301 moveto
+(SemiGroup\(\))
+[7.68 6.24 10.8 3.84 10.08 4.8 6.96 6.96 6.96 4.56 4.56]
+xshow
+end grestore
+end grestore
+% 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
+% SemiGroup()->SetCategory()
+newpath 232 288 moveto
+221 279 207 268 195 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 197 255 moveto
+187 252 lineto
+193 261 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 197 255 moveto
+187 252 lineto
+193 261 lineto
+closepath
+stroke
+end grestore
+% RepeatedSquaring(SemiGroup)
+gsave 10 dict begin
+filled
+0.333 1.000 0.933 nodecolor
+0.333 1.000 0.933 nodecolor
+newpath 442 252 moveto
+250 252 lineto
+250 216 lineto
+442 216 lineto
+closepath
+fill
+0.333 1.000 0.933 nodecolor
+newpath 442 252 moveto
+250 252 lineto
+250 216 lineto
+442 216 lineto
+closepath
+stroke
+gsave 10 dict begin
+0.000 0.000 0.000 nodecolor
+258 229 moveto
+(RepeatedSquaring\(SemiGroup\))
+[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 7.68 6.24 10.8 3.84 10.08 4.8 6.96 6.96 6.96 4.56]
+xshow
+end grestore
+end grestore
+% SemiGroup()->RepeatedSquaring(SemiGroup)
+newpath 278 288 moveto
+289 279 303 268 315 258 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 317 261 moveto
+323 252 lineto
+313 255 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 317 261 moveto
+323 252 lineto
+313 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(SemiGroup)->RepeatedSquaring(a:SetCategory)
+newpath 351 216 moveto
+354 208 357 199 359 190 curveto
+stroke
+gsave 10 dict begin
+solid
+1 setlinewidth
+0.000 0.000 0.000 edgecolor
+newpath 362 191 moveto
+362 180 lineto
+356 189 lineto
+closepath
+fill
+0.000 0.000 0.000 edgecolor
+newpath 362 191 moveto
+362 180 lineto
+356 189 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
+% 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
+endpage
+showpage
+grestore
+%%PageTrailer
+%%EndPage: 1
+%%Trailer
+%%Pages: 1
+end
+restore
+%%EOF
diff --git a/changelog b/changelog
index 74e0af1..4671a53 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,9 @@
+20080918 tpd books/ps/v102semigroup.ps diagram SGROUP
+20080918 tpd books/ps/v102orderedset.ps diagram ORDSET
+20080918 tpd books/ps/v102finite.ps diagram FINITE
+20080918 tpd src/algebra/catdef.spad remove FINITE, ORDSET, SGROUP
+20080918 tpd books/ps/v102homogeneousaggregate.ps corrected diagram
+20080918 tpd books/bookvol10.2 add FINITE, ORDSET, SGROUP
 20080917 tpd src/algebra/catdef.spad remove BASTYPE, SETCAT, ABELSG
 20080917 tpd books/ps/v102abeliansemigroup.ps ABELSG graph
 20080917 tpd books/ps/v102setcategory.ps SETCAT graph
diff --git a/src/algebra/catdef.spad.pamphlet b/src/algebra/catdef.spad.pamphlet
index bd42900..6b2ac80 100644
--- a/src/algebra/catdef.spad.pamphlet
+++ b/src/algebra/catdef.spad.pamphlet
@@ -2012,47 +2012,6 @@ Field(): Category == 
Join(EuclideanDomain,UniqueFactorizationDomain,
       divide(x,y) == [x / y,0]
 
 @
-\section{category FINITE Finite}
-<<dot>>=
-"FINITE" -> "SETCAT"
-"Finite()" -> "SetCategory()"
-@
-<<category FINITE Finite>>=
-)abbrev category FINITE Finite
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ The category of domains composed of a finite set of elements.
-++ We include the functions \spadfun{lookup} and \spadfun{index} to give a 
bijection
-++ between the finite set and an initial segment of positive integers.
-++
-++ Axioms:
-++   \spad{lookup(index(n)) = n}
-++   \spad{index(lookup(s)) = s}
-
-Finite(): Category == SetCategory with
-    --operations
-      size: () ->  NonNegativeInteger
-        ++ size() returns the number of elements in the set.
-      index: PositiveInteger -> %
-        ++ index(i) takes a positive integer i less than or equal
-        ++ to \spad{size()} and
-        ++ returns the \spad{i}-th element of the set. This operation 
establishs a bijection
-        ++ between the elements of the finite set and \spad{1..size()}.
-      lookup: % -> PositiveInteger
-        ++ lookup(x) returns a positive integer such that
-        ++ \spad{x = index lookup x}.
-      random: () -> %
-        ++ random() returns a random element from the set.
-
-@
 \section{category FLINEXP FullyLinearlyExplicitRingOver}
 <<dot>>=
 "FLINEXP" -> "LINEXP"
@@ -3471,58 +3430,6 @@ Note that this code is not included in the generated 
catdef.spad file.
                1 6 0 0 18 1 0 16 0 17 1 0 8 0 10 1 0 8 0 11 1 0 0 0 19))))))
    (QUOTE |lookupComplete|))) 
 @
-\section{category ORDSET OrderedSet}
-<<dot>>=
-"ORDSET" -> "SETCAT"
-"OrderedSet()" -> "SetCategory()"
-@
-<<category ORDSET OrderedSet>>=
-)abbrev category ORDSET OrderedSet
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ The class of totally ordered sets, that is, sets such that for each pair of 
elements \spad{(a,b)}
-++ exactly one of the following relations holds \spad{a<b or a=b or b<a}
-++ and the relation is transitive, i.e.  \spad{a<b and b<c => a<c}.
-
-OrderedSet(): Category == SetCategory with
-  --operations
-    "<": (%,%) -> Boolean
-      ++ x < y is a strict total ordering on the elements of the set.
-    ">":         (%, %) -> Boolean
-      ++ x > y is a greater than test.
-    ">=":        (%, %) -> Boolean
-      ++ x >= y is a greater than or equal test.
-    "<=":        (%, %) -> Boolean
-      ++ x <= y is a less than or equal test.
-
-    max: (%,%) -> %
-      ++ max(x,y) returns the maximum of x and y relative to "<".
-    min: (%,%) -> %
-      ++ min(x,y) returns the minimum of x and y relative to "<".
-  add
-  --declarations
-    x,y: %
-  --definitions
-  -- These really ought to become some sort of macro
-    max(x,y) ==
-      x > y => x
-      y
-    min(x,y) ==
-      x > y => y
-      x
-    ((x: %) >  (y: %)) : Boolean == y < x
-    ((x: %) >= (y: %)) : Boolean == not (x < y)
-    ((x: %) <= (y: %)) : Boolean == not (y < x)
-
-@
 \section{category PDRING PartialDifferentialRing}
 <<dot>>=
 "PDRING" -> "RING"
@@ -3957,51 +3864,6 @@ Note that this code is not included in the generated 
catdef.spad file.
 (MAKEPROP (QUOTE |Rng|) (QUOTE NILADIC) T) 
 
 @
-\section{category SGROUP SemiGroup}
-A Semigroup is defined as a set $S$ with a binary multiplicative
-operator ``*''. A Semigroup $G(S,*)$ is:
-\begin{itemize}
-\item a set $S$ which can be null
-\item a binary multiplicative operator ``*''
-\item associative. $\forall a,b,c \in S, a*(b*c) = (a*b)*c$
-\end{itemize}
-<<dot>>=
-"SGROUP" -> "SETCAT"
-"SemiGroup()" -> "SetCategory()"
-@
-<<category SGROUP SemiGroup>>=
-)abbrev category SGROUP SemiGroup
-++ Author:
-++ Date Created:
-++ Date Last Updated:
-++ Basic Functions:
-++ Related Constructors:
-++ Also See:
-++ AMS Classifications:
-++ Keywords:
-++ References:
-++ Description:
-++ the class of all multiplicative semigroups, i.e. a set
-++ with an associative operation \spadop{*}.
-++
-++ Axioms:
-++    \spad{associative("*":(%,%)->%)}\tab{30}\spad{ (x*y)*z = x*(y*z)}
-++
-++ Conditional attributes:
-++    \spad{commutative("*":(%,%)->%)}\tab{30}\spad{ x*y = y*x }
-SemiGroup(): Category == SetCategory with
-    --operations
-      "*": (%,%) -> %                  ++ x*y returns the product of x and y.
-      "**": (%,PositiveInteger) -> %   ++ x**n returns the repeated product
-                                       ++ of x n times, i.e. exponentiation.
-      "^": (%,PositiveInteger) -> %    ++ x^n returns the repeated product
-                                       ++ of x n times, i.e. exponentiation.
-    add
-      import RepeatedSquaring(%)
-      x:% ** n:PositiveInteger == expt(x,n)
-      _^(x:%, n:PositiveInteger):% == x ** n
-
-@
 \section{category STEP StepThrough}
 <<dot>>=
 "STEP" -> "SETCAT"
@@ -4322,7 +4184,6 @@ VectorSpace(S:Field): Category ==  Module(S) with
 <<license>>
 
 <<category STEP StepThrough>>
-<<category SGROUP SemiGroup>>
 <<category MONOID Monoid>>
 <<category GROUP Group>>
 <<category ABELMON AbelianMonoid>>
@@ -4349,9 +4210,7 @@ VectorSpace(S:Field): Category ==  Module(S) with
 <<category EUCDOM EuclideanDomain>>
 <<category DIVRING DivisionRing>>
 <<category FIELD Field>>
-<<category FINITE Finite>>
 <<category VSPACE VectorSpace>>
-<<category ORDSET OrderedSet>>
 <<category ORDFIN OrderedFinite>>
 <<category ORDMON OrderedMonoid>>
 <<category OASGP OrderedAbelianSemiGroup>>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]