%MACROS FOR CATEGORY THEORY AND SEMANTICS - J. C. Reynolds - March 1988

%This file (catmac.tex) contains macros for a variety of notations used in
%category theory and semantics.  A second file catmactest.tex is an input
%file for LATEX that tests the macros in this file.  A third file
%largeoptest.tex is an input file for LATEX that does additional
%tests of the large operators with both limits and scripts.

%These macros were designed for use with Computer Modern fonts, in a LATEX
%document style with the 12pt option, using an Apple Laserwriter for output.
%Most but not all of the macros should work with other fonts, sizes, and
%printers; comments marked ``FONT DEPENDENCY'' indicate potential problems.

%We adopt the convention that control symbols denoting registers and macros
%that should be hidden from the user begin with \yy.


%REGISTERS AND BOXES

\newcount\yyitercn %Used by iterative definitions
\newcount\yycnA %Used by \defbig

\newbox\yybxA %Used by \makelevel,\defbig,\kernpart,\embolden,\defaxis,
%    \yyarrowb,\multscript,\compscript
\newbox\yybxB %Used by \Glb,\multscript,\compscript,\Glbms
\newbox\yybxC %Used by \multscript,\compscript
\newbox\yybxD %Used by \multscript,\compscript
\newbox\yybxE %Used by \multscript,\compscript
\newbox\yybxF %Used by \multscript,\compscript
\newbox\yybxG %Used by \multscript,\compscript

\newdimen\yydmA %Used by \makelevel,\defbig,\kernpart,\yyarrowb,
%    \multscript,\compscript
\newdimen\yydmB %Used by \defbig,\multscript,\compscript
\newdimen\yydmC %Used by \defbig,\multscript,\compscript
\newdimen\yydmD %Used by \multscript,\compscript
\newdimen\yydmE %Used by \multscript,\compscript
\newdimen\yydmF %Used by \multscript,\compscript
\newdimen\yydmG %Used by \multscript
\newdimen\yydmH %Used by \multscript
\newdimen\yydmI %Used by \multscript



%MISCELLANEOUS SPECIAL SYMBOLS AND OTHER MACROS

%\defaxis defines #1 to stand for a dimension giving the height of the axis
%in the math style #2.  It is used to define \displayaxis, \textaxis,
%\scriptaxis, and \scriptscriptaxis to stand for the height of the axis
%in the four styles.  These control symbols affect the relation macros
%\arrow... and \Arrow... described later.  The user may also use them
%to define the control symbol \centerheight used by the diagram macros
%in the file diagmac.tex (e.g. \def\centerheight{\displayaxis}).

\def\defaxis#1#2{\setbox\yybxA=\hbox{{$#2\vcenter{}$}}
\edef#1{\the\ht\yybxA}}

\defaxis\displayaxis\displaystyle
\defaxis\textaxis\textstyle
\defaxis\scriptaxis\scriptstyle
\defaxis\scriptscriptaxis\scriptscriptstyle

%\eqper and \eqcom are a period and comma designed to end displayed equations.
%The effect is to place a space before the period or comma.

\def\eqper{\: .}
\def\eqcom{\: ,}

%The following macros give notations for the reflection and inverse of
%relations and functions, the dual of categories, and identity morphisms.
%For \identgen the first parameter is the category and the second is
%the object.  For \ident the category is omitted and the only parameter
%is the name of the object.

\def\reflect#1{{#1}^\dagger}
\def\inverse#1{{#1}^{-1}}
\def\dual#1{{#1}^{\rm op}}
\def\identgen#1#2{I^{#1}_{#2}}
\def\ident#1{I_{#1}}

%\startproof and \endproof are used to enclose proofs. \endproof prints
%``End of Proof'' right-adjusted, either on the current line, or on a new line
%if the current line is too full.  It is a variation of the macro given
%on page 106 of The TEXbook.

%These are the only macros in this file designed to be called outside of
%math mode.

\def\startproof{{\em Proof\/}: }

\def\endproof{{\unskip\nobreak\hfil\penalty50
\hskip1em\hbox{}\nobreak\hfil({\em End of Proof\/})
\parfillskip=0pt \finalhyphendemerits=0 \par}}


%UNARY OPERATORS

%The following macros define function symbols for the domain and range
%of functions, the size of sets, the (sets of) objects and morphisms
%of a category, and the application and abstraction morphisms in a
%Cartesian closed category.

%Except for \sizeop, these symbols have type Op with the \nolimits option,
%so that they will be slightly separated from adjacent symbols and can be
%given subscripts and superscripts.  The symbol \sizeop has type Ord, so
%that it is not separated from adjacent ordinary symbols. (See page 170
%of the TEXbook.)

\def\domainop{\mathop{\rm dom}\nolimits}
\def\rangeop{\mathop{\rm ran}\nolimits}
\def\sizeop{\mathord{\#}}
\def\objectsop{\mathop{\rm Ob}\nolimits}
\def\morphsop{\mathop{\rm Mor}\nolimits}
\def\apop{\mathop{\sf ap}\nolimits}
\def\abop{\mathop{\sf ab}\nolimits}


%BINARY OPERATORS

%The following macros give binary operators for restriction and corestriction
%of functions and relations, diagrammatic-order composition of morphisms
%(a semicolon), and Godement multiplication (a boxed semicolon).

%\restrictop and \corestrictop are made ordinary symbols rather than
%binary operators so that less space is placed on either side.

\def\restrictop{\mathord{\rceil}}
\def\corestrictop{\mathord{\lceil}}

\def\sccompop{\mathbin{;}}

%FONT DEPENDENCY: \godmult is specific to computer modern fonts, 12pt style,
%and the Apple laserwriter.  For some reason, it doesn't center the
%semicolon properly on a VAX laserwriter.

\def\godmult{\mathbin{\mathchoice
{\kern0.25pt\vrule height7pt depth3.5pt
\vrule height7pt depth-6.6pt width4pt
\kern-4pt\vrule height-3.1pt depth3.5pt width4pt
\kern-3.3pt\textstyle ;\kern-0.03333pt
\vrule height7pt depth3.5pt\kern1pt}
{\kern0.25pt\vrule height7pt depth3.5pt
\vrule height7pt depth-6.6pt width4pt
\kern-4pt\vrule height-3.1pt depth3.5pt width4pt
\kern-3.3pt\textstyle ;\kern-0.03333pt
\vrule height7pt depth3.5pt\kern1pt}
{\kern0.5pt\vrule height5pt depth2.5pt
\vrule height5pt depth-4.6pt width3pt
\kern-3pt\vrule height-2.1pt depth2.5pt width3pt
\kern-2.4pt\scriptstyle ;\kern0.03889pt
\vrule height5pt depth2.5pt\kern1pt}
{\kern0.5pt\vrule height4.25pt depth2pt
\vrule height4.25pt depth-3.85pt width2.75pt
\kern-2.75pt\vrule height-1.6pt depth2pt width2.75pt
\kern-2.275pt\scriptscriptstyle ;\kern-0.00277pt
\vrule height4.25pt depth2pt\kern1pt}}}


%RELATIONS

%The following macros give binary relation symbols for definitional
%equality, inequality, finite subset, and membership, nonmembership,
%and unique membership in a set.

\def\eqdef{\buildrel \rm def \over =}

\def\noteq{\mathrel{\not=}}

\def\finsubset{\buildrel \rm fin \over \subseteq}

%FONT DEPENDENCY: The symbols \in and \notin are redefined to give smaller
%symbols than in the Computer Modern fonts.  The unmodified symbols can be
%obtained with \oldin and \oldnotin.  If the user does not wish these symbols
%to be modified, this set of definitions should be deleted.

%The subsidiary macro \makelevel, which is used only by \in and \notin,
%prints its arguemt raised to have depth zero.

\let\oldin=\in
\let\yyoldnotinraw=\notin %Internal
\def\oldnotin{\mathrel{{\def\in{\oldin}\yyoldnotinraw}}}

\def\in{\mathrel{\mathchoice
{\makelevel{\scriptstyle\oldin}}
{\makelevel{\scriptstyle\oldin}}
{\makelevel{\scriptscriptstyle\oldin}}
{\scriptscriptstyle\oldin}}}

\def\notin{\mathrel{\mathchoice
{\makelevel{\scriptstyle\oldnotin}}
{\makelevel{\scriptstyle\oldnotin}}
{\makelevel{\scriptscriptstyle\oldnotin}}
{\scriptscriptstyle\oldnotin}}}

\def\makelevel#1{\setbox\yybxA=\hbox{$\mathsurround=0pt{#1}$}
\yydmA=\dp\yybxA \raise\yydmA\hbox{$\mathsurround=0pt{#1}$}}

%End of redefinitions of \in and \notin.

\def\uniquein{\mathrel{{\in}!}}

%The following macros draw arrows with centered subscripts and superscripts.
%The arrows are lengthened to extend beyond the ends of the scripts.
%\arrow... draws an arrow with a single shaft, while \Arrow... draws an
%arrow with a double shaft.  All arrows are centered on the axis.

%A single-shafted arrow, perhaps subscripted with the name of the relevant
%category, is used as a binary operation giving the set of morphisms
%between two objects (or more generally as the external hom-functor).
%(The name of a morphism might appear as a superscript.)
%A double-shafted arrow, perhaps subscripted with the name of the relevant
%category, is used to denote exponentiation in a Cartesian closed category
%(or more generally the internal hom-functor).

\def\arrow{\rightarrow}
\def\arrowsub#1{\yyarrowa{_{#1}}}
\def\arrowsuper#1{\yyarrowa{^{#1}}}
\def\arrowsubsuper#1#2{\yyarrowa{_{#1}^{#2}}}

\def\Arrow{\Rightarrow}
\def\Arrowsub#1{\yyArrowa{_{#1}}}
\def\Arrowsuper#1{\yyArrowa{^{#1}}}
\def\Arrowsubsuper#1#2{\yyArrowa{_{#1}^{#2}}}

\def\yyarrowa#1{\mathrel{\mathchoice %Internal
{\yyarrowb\yyrightarrowfill\displaystyle\displayaxis{#1}{0ex}{0ex}
{6mu}{8mu}\rightarrow}
{\yyarrowb\yyrightarrowfill\textstyle\textaxis{#1}{0ex}{0ex}
{6mu}{8mu}\rightarrow}
{\yyarrowb\yyrightarrowfill\scriptstyle\scriptaxis{#1}{0ex}{0ex}
{6mu}{8mu}\rightarrow}
{\yyarrowb\yyrightarrowfill\scriptscriptstyle
\scriptscriptaxis{#1}{0ex}{0ex}{6mu}{8mu}\rightarrow}}}

\def\yyArrowa#1{\mathrel{\mathchoice %Internal
{\yyarrowb\yyRightarrowfill\displaystyle\displayaxis{#1}{0.2ex}{0.2ex}
{6mu}{12mu}\Rightarrow}
{\yyarrowb\yyRightarrowfill\textstyle\textaxis{#1}{0.2ex}{0.2ex}
{6mu}{12mu}\Rightarrow}
{\yyarrowb\yyRightarrowfill\scriptstyle\scriptaxis{#1}{0.1ex}{0ex}
{6mu}{12mu}\Rightarrow}
{\yyarrowb\yyRightarrowfill\scriptscriptstyle
\scriptscriptaxis{#1}{0.1ex}{0ex}{6mu}{12mu}\Rightarrow}}}

\def\yyarrowb#1#2#3#4#5#6#7#8#9{{ %Internal
\setbox\yybxA=\hbox{$\mathsurround=0pt #2
\mkern #7\mathop{}\limits #4\mkern #8$}
\yydmA=\wd\yybxA\relax
\setbox\yybxA=\hbox{$\mathsurround=0pt #2 #9$}
\ifdim\yydmA<\wd\yybxA\relax\yydmA=\wd\yybxA\relax\else\fi
\setbox\yybxA=\hbox to \yydmA{#1 #2}
\yydmA=#3\relax\advance\yydmA by #5\relax\ht\yybxA=\yydmA\relax
\yydmA=-#3\relax\advance\yydmA by #6\relax\dp\yybxA=\yydmA\relax
#2\mathop{\box\yybxA}\limits #4}}

\def\yyrightarrowfill#1{$\mathsurround=0pt #1\mathord- \mkern-9mu %Internal
\cleaders\hbox{$#1\mkern-3mu \mathord- \mkern-3mu$}\hfill
\mkern-9mu \mathord\rightarrow$}

\def\yyRightarrowfill#1{$\mathsurround=0pt #1\mathord= \mkern-9mu %Internal
\cleaders\hbox{$#1\mkern-3mu \mathord= \mkern-3mu$}\hfill
\mkern-9mu \mathord\Rightarrow$}


%DELIMITERS

%Here we define a variety of macros for dealing with variable-sized
%delimiters.  

%The plain TEX macros \big, \Big, \bigg, and \Bigg (and their cousins such
%as \bigl, \bigm, and \bigr) are specifically designed for Computer Modern
%fonts in 10pt style, and do not work appropriately with, for example,
%12pt style.  The following macros attempt to cure this problem.

%The macro \defbig is used to define macros akin to \big, \Big, etc.
%\defbig<style><old control symbol><new control symbol>{<dimen>} defines
%<new control symbol> to be such a macro such that <new control symbol>(
%has a depth at least <dimen> more than <old control symbol>(.
%(Except that the dimension in the \vbox command of the new macro
%will not exceed the height of <old control symbol>( by more than
%10pt, even if this has no effect on the symbol size.)
%Note that <old control symbol> can be \relax.
%The parameter <style> is the style in which ( (or any other argument
%to the macro) is to be printed. 

\def\defbig#1#2#3#4{\setbox\yybxA=\hbox{$#1#2($}
\yydmA=\ht\yybxA\relax\yydmB=\dp\yybxA\relax\yycnA=50\relax
\yydefbiga{#1}{#3}{#4}}

\def\yydefbiga#1#2#3{\advance\yydmA by 0.2pt\relax %Internal
\advance\yycnA by -1\relax
\setbox\yybxA=\hbox{$#1\left(\vbox to \yydmA{}\right.
\nulldelimiterspace=0pt\mathsurround=0pt$}
\yydmC=\dp\yybxA\relax\advance\yydmC by -\yydmB\relax
\advance\yydmC by -#3\relax
\ifdim\yydmC<0pt\relax\ifnum\yycnA>0\relax
\yydefbiga{#1}{#2}{#3}
\else\yydefbigb{#2}{#1}\fi
\else\yydefbigb{#2}{#1}\fi}

\def\yydefbigb#1#2{\edef\yybigsize{{\the\yydmA}} %Internal
\expandafter\yydefbigc\yybigsize{#1}{#2}}

\def\yydefbigc#1#2#3{\def#2##1{{\hbox{$#3\left##1\vbox to #1{}\right. %Internal
\nulldelimiterspace=0pt\mathsurround=0pt$}}}}

%The following calls of \defbig redefine \big, \Big, \bigg, and \Bigg
%in a way that works well for any reasonable font and size.
%They may be deleted if the predefined versions of these control symbols
%are satisfactory (which they are not in 12pt style Computer Modern fonts).
%Note that these redefinitions also affect \bigl, \bigm, \bigr, \Bigl, etc.
%Also note that the \big... macros should only be used in display style
%and text style.

\defbig\textstyle\relax\big{0.95pt}
\defbig\textstyle\big\Big{0.95pt}
\defbig\textstyle\Big\bigg{0.95pt}
\defbig\textstyle\bigg\Bigg{0.95pt}

%The following calls of \defbig define analogues of \big, \bigl, \bigm, and
%\bigr for script style and scriptscript style.  They should only be used
%in these styles.

\defbig\scriptstyle\relax\scriptbig{0.95pt}
\defbig\scriptscriptstyle\relax\scriptscriptbig{0.95pt}
\def\scriptbigl{\mathopen\scriptbig}
\def\scriptbigm{\mathrel\scriptbig}
\def\scriptbigr{\mathclose\scriptbig}
\def\scriptscriptbigl{\mathopen\scriptscriptbig}
\def\scriptscriptbigm{\mathrel\scriptscriptbig}
\def\scriptscriptbigr{\mathclose\scriptscriptbig}

%Now we define a number of macros for controling the size of delimiters.
%The basic idea is to introduce a control symbol \currbig, which may denote
%\relax, \big, \Big, etc., and which affects the size of delimiters
%printed by other macros.

%The following macros open a group, define \currbig appropriately, and
%then execute their argument within the group.  (\Bigsize, \biggsize, and 
%\Biggsize also make their argument a \mathinner symbol, so that it will
%be surrounded by extra space.)

\def\normsize#1{\begingroup\let\currbig=\relax #1\endgroup}
\def\bigsize#1{\begingroup\let\currbig=\big #1\endgroup}
\def\Bigsize#1{\mathinner{{\let\currbig=\Big #1}}}
\def\biggsize#1{\mathinner{{\let\currbig=\bigg #1}}}
\def\Biggsize#1{\mathinner{{\let\currbig=\Bigg #1}}}
\def\scriptbigsize#1{\begingroup\let\currbig=\scriptbig #1\endgroup}
\def\scriptscriptbigsize#1{\begingroup\let\currbig=\scriptscriptbig
#1\endgroup}

%The following defines \currbig to be \relax outside of the groups
%established by the previous macros, so that the variable-sized
%delimiters will be normal sized.

\let\currbig=\relax

%The following macros define the variable-sized delimiters, whose size is
%conditioned by the meaning of \currbig.  Note that \varlvert, \varrvert,
%and \varmid give the same symbol (|) with different types: Open, Close,
%and Rel.

\def\varlpar{\mathopen\currbig(}
\def\varrpar{\mathclose\currbig)}
\def\varlbrack{\mathopen\currbig\lbrack}
\def\varrbrack{\mathclose\currbig\rbrack}
\def\varlbrace{\mathopen\currbig\lbrace}
\def\varrbrace{\mathclose\currbig\rbrace}
\def\varlangle{\mathopen\currbig\langle}
\def\varrangle{\mathclose\currbig\rangle}
\def\varlvert{\mathopen\currbig\vert}
\def\varrvert{\mathclose\currbig\vert}
\def\varmid{\mathrel\currbig\vert}

%\varlsembr and \varrsembr give semantic brackets, i.e. double square
%brackets.

%FONT DEPENDENCY: It may be necesssary to vary the parameter -59 in these
%macros for different fonts.

\def\varlsembr{\mathopen{{\currbig\lbrack
\kernpart{\currbig\lbrack}{-59}\currbig\lbrack}}}

\def\varrsembr{\mathclose{{\currbig\rbrack
\kernpart{\currbig\rbrack}{-59}\currbig\rbrack}}}

%\kernpart{#1}{#2} does a kern of width #2/100 times the width of #1.

\def\kernpart#1#2{\mathchoice
{\yykernparta{\displaystyle#1}{#2}}
{\yykernparta{\textstyle#1}{#2}}
{\yykernparta{\scriptstyle#1}{#2}}
{\yykernparta{\scriptscriptstyle#1}{#2}}}

\def\yykernparta#1#2{ %Internal
\setbox\yybxA=\hbox{$\mathsurround=0pt\relax #1$}
\yydmA=\wd\yybxA\multiply\yydmA by #2\relax
\divide\yydmA by 100\relax \kern\yydmA}

%\varbdlangle and \varbdrangle give (poor man's) boldface angle brackets.

%FONT DEPENDENCY: It may be necessary to vary the parameter .025em in these
%macros for different fonts.

\def\varbdlangle{\mathopen{{\embolden{\currbig\langle}{.025em}}}}
\def\varbdrangle{\mathclose{{\embolden{\currbig\rangle}{.025em}}}}

%\embolden{#1}{#2} overprints #1 four times, displaced up, down, left, and
%right by the dimension #2.

\def\embolden#1#2{\mathchoice
{\yyemboldena{\displaystyle#1}{#2}}
{\yyemboldena{\textstyle#1}{#2}}
{\yyemboldena{\scriptstyle#1}{#2}}
{\yyemboldena{\scriptscriptstyle#1}{#2}}}

\def\yyemboldena#1#2{ %Internal
\setbox\yybxA=\hbox{$\mathsurround=0pt\relax #1$}
\copy\yybxA\kern-\wd\yybxA\kern #2\relax
\raise #2\copy\yybxA\kern-\wd\yybxA\relax
\raise -#2\copy\yybxA\kern-\wd\yybxA\kern #2\relax
\box\yybxA}

%Finally, we define several ``balanced delimiter'' macros, which enclose
%their arguments in balanced delimiters.  The size of these enclosing
%delimiters (and of the symbol | in \setdef) are controlled by \currbig,
%but \normsize is applied to the arguments, so that delimiters within the
%arguments will be normal size (unless \currbig is changed).  Thus for example,
%\bigsize{\paren{\paren{x}}} and \Bigsize{\paren{\bigsize{\paren{\paren{x}}}}}
%surround x with two or three pairs of parentheses of increasing size.

\def\paren#1{\varlpar\normsize{#1}\varrpar}
\def\carrier#1{\varlvert\normsize{#1}\varrvert}
\def\setdef#1#2{\varlbrace\nonscript\,\normsize{#1}\varmid
\normsize{#2}\nonscript\,\varrbrace}
\def\sembr#1{\varlsembr\normsize{#1}\varrsembr}


%MACROS WITH A VARIABLE NUMBER OF PARAMETERS

%In this section we give a number of macros accepting a variable number of
%parameters (as well as a few conventional but closely related macros such
%as \emptyset and \sqpairlistdots).  These are macros whose first parameter
%is an integer determining the number of further parameters.

%\simplist accepts a nonnegative integer n, a left delimiter, a right
%delimiter, a separating symbol, an ``empty list'', and n further parameters.
%If n = 0 it produces the empty list.  Otherwise, it produces a list of
%the n parameters, separated by the separating symbol and enclosed by the
%delimiters. The n parameters are each executed within a call of \normsize.

%\simplist is used to define a collection of macros with specific delimiters
%and separating symbols.  In each case, variable-size delimiters are used,
%so that the size of these delimiters (but not of those within the parameters
%to the macro) are affected by the meaning of \currbig when the macro
%is executed.  Thus these macros behave like the balanced delimiter macros
%given above.

\def\simplist#1#2#3#4#5{
% #1 = number of operands
% #2 = left delimiter
% #3 = right delimiter
% #4 = separating symbol
% #5 = emptylist
\yyitercn=#1\relax
\def\yyrightdel{#3}
\def\yysepsym{#4}
\ifnum\yyitercn=0\relax
#5 \let\next=\relax
\else #2 \let\next=\yysimplista
\fi\next}

\def\yysimplista#1{\begingroup\normsize{#1}\endgroup %Internal
\advance\yyitercn by -1\relax
\ifnum\yyitercn=0\relax
\yyrightdel \let\next=\relax
\else \yysepsym \let\next=\yysimplista
\fi\next}

\def\emptyset{\varlbrace\varrbrace}

\def\setlist#1{\simplist{#1}\varlbrace\varrbrace{,}\emptyset}

\def\emptysqlist{\varlbrack\,\varrbrack}

\def\sqlist#1{\simplist{#1}\varlbrack\varrbrack{,}\emptysqlist}

\def\emptyanglelist{\varlangle\varrangle}

\def\anglelist#1{\simplist{#1}\varlangle\varrangle{,}\emptyanglelist}

\def\emptybdanglelist{\varbdlangle\varbdrangle}

\def\bdanglelist#1{\simplist{#1}\varbdlangle\varbdrangle{,}\emptybdanglelist}

%\pairlist accepts a nonnegative integer n, a left delimiter, a right
%delimiter, a separating symbol, a pairing symbol, an empty list, and 2n
%further parameters.  If n = 0 it produces the empty list.  Otherwise,
%it produces a list of the 2n parameters, grouped into pairs joined by
%the pairing symbol, where the pairs are separated by the separating
%symbol and enclosed by the delimiters.  The 2n parameters are each
%executed within a call of \normsize.

%\pairlistdots is similar to \pairlist2, except that the single occurrence
%of the separating symbol is replaced by two occurrences with \ldots
%between them.

%\pairlist and \pairlistdots are used to define a collection of macros
%with specific delimiters, separating symbols, and pairing symbols.
%Variable-sized delimiters (and the variable-sized separating symbol \varmid)
%are used, so that the size of these delimiters (but not of those within
%the parameters) are affected by the meaning of \currbig when the macro
%is executed.  Thus these macros behave like the balanced delimiter macros.

%These notations are used to specify functions by giving a list of
%argument-result pairs.

\def\pairlist#1#2#3#4#5#6{
% #1 = number of operands
% #2 = left delimiter
% #3 = right delimiter
% #4 = separating symbol
% #5 = pairing symbol
% #6 = emptylist
\yyitercn=#1\relax
\def\yyrightdel{#3}
\def\yysepsym{#4}
\def\yypairsym{#5}
\ifnum\yyitercn=0\relax
#6 \let\next=\relax
\else #2 \let\next=\yypairlista
\fi\next}

\def\yypairlista#1#2{ %Internal
\begingroup\normsize{#1}\endgroup\yypairsym
\begingroup\normsize{#2}\endgroup
\advance\yyitercn by -1\relax
\ifnum\yyitercn=0\relax
\yyrightdel \let\next=\relax
\else \yysepsym \let\next=\yypairlista
\fi\next}

\def\pairlistdots#1#2#3#4#5#6#7#8{
% #1 = left delimiter
% #2 = right delimiter
% #3 = separating symbol
% #4 = pairing symbol
% #5 = left side of first pair
% #6 = right side of first pair
% #7 = left side of last pair
% #8 = right side of last pair
#1\begingroup\normsize{#5}\endgroup #4
\begingroup\normsize{#6}\endgroup #3
\ldots #3\begingroup\normsize{#7}\endgroup #4
\begingroup\normsize{#8}\endgroup #2}

\def\sqpairlist#1{\pairlist{#1}
{\varlbrack\nonscript\,}{\nonscript\,\varrbrack}\varmid\colon\emptysqlist}

\def\sqpairlistdots{\pairlistdots
{\varlbrack\nonscript\,}{\nonscript\,\varrbrack}\varmid\colon}

\def\anglepairlist#1{\pairlist{#1}
{\varlangle\nonscript\,}{\nonscript\,\varrangle}\varmid\colon\emptyanglelist}

\def\anglepairlistdots{\pairlistdots
{\varlangle\nonscript\,}{\nonscript\,\varrangle}\varmid\colon}

\def\bdanglepairlist#1{\pairlist{#1}
{\varbdlangle\nonscript\,}{\nonscript\,\varbdrangle}\varmid\colon
\emptybdanglelist}

\def\bdanglepairlistdots{\pairlistdots
{\varbdlangle\nonscript\,}{\nonscript\,\varbdrangle}\varmid\colon}

%\pairext accepts a nonnegative integer n, a left delimiter, a right
%delimiter, a separating symbol, a pairing symbol, and 2n+1 further
%parameters.  It produces a list of the 2n+1 parameters similar to
%that produced by \pairlist, except that the first of these parameter
%appears by itself in place of a pair.

%\pairextdots is similar to \pairext2, except that the last occurrence
%of the separating symbol is replaced by two occurrences with \ldots
%between them.

%\pairext and \pairextdots are used to define a collection of macros
%with specific delimiters, separating symbols, and pairing symbols.
%Variable-sized delimiters (and the variable-sized separating symbol \varmid)
%are used, so that the size of these delimiters (but not of those within
%the parameters) are affected by the meaning of \currbig when the macro
%is executed.  Thus these macros behave like the balanced delimiter macros.

%These notations are used to define functions by varying a given function
%(the first of the 2n+1 parameters) at n points.

\def\pairext#1#2#3#4#5#6{
% #1 = number of operands
% #2 = left delimiter
% #3 = right delimiter
% #4 = separating symbol
% #5 = pairing symbol
% #6 = preliminary subexpression
\pairlist{#1}{#2\begingroup\normsize{#6}\endgroup #4}
{#3}{#4}{#5}{#2\begingroup\normsize{#6}\endgroup #3}}

\def\pairextdots#1#2#3#4#5#6#7#8#9{
% #1 = left delimiter
% #2 = right delimiter
% #3 = separating symbol
% #4 = pairing symbol
% #5 = preliminary subexpression
% #6 = left side of first pair
% #7 = right side of first pair
% #8 = left side of last pair
% #9 = right side of last pair
\pairlistdots{#1\begingroup\normsize{#5}\endgroup #3}
{#2}{#3}{#4}{#6}{#7}{#8}{#9}}

\def\sqpairext#1{\pairext{#1}
{\varlbrack\nonscript\,}{\nonscript\,\varrbrack}\varmid\colon}

\def\sqpairextdots{\pairextdots
{\varlbrack\nonscript\,}{\nonscript\,\varrbrack}\varmid\colon}

\def\anglepairext#1{\pairext{#1}
{\varlangle\nonscript\,}{\nonscript\,\varrangle}\varmid\colon}

\def\anglepairextdots{\pairextdots
{\varlangle\nonscript\,}{\nonscript\,\varrangle}\varmid\colon}

\def\bdanglepairext#1{\pairext{#1}
{\varbdlangle\nonscript\,}{\nonscript\,\varbdrangle}\varmid\colon}

\def\bdanglepairextdots{\pairextdots
{\varbdlangle\nonscript\,}{\nonscript\,\varbdrangle}\varmid\colon}

%\infix accepts a positive integer n, a separating symbol, and n further
%parameters.  It produces a list of the n parameters separated by the
%separating symbol.  The n parameters are executed directly (not within
%a call of \normsize) so that they are affected by the meaning of \currbig
%when the macro is executed.

%\infix is used to define a collection of macros with specific separating
%symbols.  For example, \compo3{a}{b}{c} gives a;b;c.

\def\infix#1#2{
% #1 = number of operands
% #2 = separating symbol
\yyitercn=#1\relax
\def\yysepsym{#2}
\ifnum\yyitercn=0\relax
\errmessage{CALL OF \string\infix0}
\let\next=\relax
\else\let\next=\yyinfixa
\fi\next}

\def\yyinfixa#1{\begingroup #1\endgroup %Internal
\advance\yyitercn by -1\relax
\ifnum\yyitercn=0\relax
\let\next=\relax
\else \yysepsym \let\next=\yyinfixa
\fi\next}

\def\compo#1{\infix{#1}{\sccompop}}
\def\compogen#1#2{\infix{#1}{\sccompop_{\normsize{#2}}}}
\def\fcompo#1{\infix{#1}{\cdot}}
\def\fcompogen#1#2{\infix{#1}{\cdot_{\normsize{#2}}}}
\def\godcompo#1{\infix{#1}{\godmult}}


%LAMBDA NOTATION

%\lambin provides a notation for lambda expressions of the ordinary typed
%lambda calculus, in which a binding occurrence of a variable is followed
%by a set-membership symbol and its type.

\def\lambin#1#2{\lambda{#1}\in{#2}.\;}

%The next three macros extend this notation to functions of several
%arguments, viewed as functions on a Cartesian product.  All three
%are variable-sized balanced delimiter macros.  \multlambin accepts a
%variable number of parameters.

\def\emptylambin{\lambda\varlangle\varrangle.\;}

\def\multlambin#1{\pairlist{#1}{\lambda\varlangle\nonscript\,}
{\nonscript\,\varrangle.\;}{,\nonscript\:}\in\emptylambin}

\def\multlambindots{\pairlistdots{\lambda\varlangle\nonscript\,}
{\nonscript\,\varrangle.\;}{,\nonscript\:}\in}

%The next macros provide a notation for the polymorphic typed lambda
%calculus, in which a binding occurrence of an ordinary variable is
%subscripted with its type.

\def\lambsub#1#2{\lambda{#1}_{#2}.\;}
\def\Lambop#1{\Lambda{#1}.\;}
\def\Deltop#1{\Delta{#1}.\;}


%LARGE OPERATORS

%Here we define variants of the large TEX operators for union, intersection,
%product, sum, and least upper bound, and also define similar operators
%for limit, colimit, and greatest lower bound.  The variants for product
%and sum are given the same names as in TEX: \prod and \sum. (The unvaried
%definitions are renamed \oldprod and \oldsum).  The other operators are
%given new names: \Union, \Intersect, \Lm, \Col, \Lub, and \Glb.

%These variants differ from the standard TEX operators in two ways,
%both of which are intended to make them look more like ``normal''
%function symbols.  First, they are smaller in script and scriptscript styles
%(where the symbols \cup, \cap, \Pi, \Sigma, \sqcup, and \sqcap are used).

%Second, the user has the option of causing the size of the operators
%in display style to be reduced to the same size as in text style,
%by calling the macro \compresslargeops, whose effect extends from the call
%to the end of the enclosing group.  An analogous macro \expandlargeops
%restores the display style size.  (These macros have no effect on \Lm and
%\Col, which are always the same size in display and text styles.)

%All of these operators obey the TEX convention that their subscripts and
%superscripts are printed as limits in display style, but not in the
%other styles.  The TEX control symbols \limits and \nolimits may be used.

%FONT DEPENDENCY:  The macro \Glb is specific to computer modern fonts
%in 12pt style, where it gives a symbol symmetric with \Lub.

%First we define the macros for compressing symbols in display style,
%and for suppressing this compression.

\def\expandlargeops{\def\yylopstyle{\displaystyle}
\def\yylopstyleswitch{1}}

\def\compresslargeops{\def\yylopstyle{\textstyle}
\def\yylopstyleswitch{0}}

%Next we make the noncompressed style a default, and save the meanings
%of the standard TEX \prod and \sum as \oldprod and \oldsum.

\expandlargeops

\let\oldprod=\prod
\let\oldsum=\sum

%Then we define the new operators.

\def\Union{\mathop{\mathchoice
{\yylopstyle\bigcup}
{\textstyle\bigcup}
{\raise-0.19355ex\hbox{$\mathsurround=0pt{\textstyle\cup}$}}
{\raise-0.13548ex\hbox{$\mathsurround=0pt{\scriptstyle\cup}$}}}}

\def\Intersect{\mathop{\mathchoice
{\yylopstyle\bigcap}
{\textstyle\bigcap}
{\raise-0.19355ex\hbox{$\mathsurround=0pt{\textstyle\cap}$}}
{\raise-0.13548ex\hbox{$\mathsurround=0pt{\scriptstyle\cap}$}}}}

\def\prod{\mathop{\mathchoice
{\yylopstyle\oldprod}
{\textstyle\oldprod}
{\scriptstyle\Pi}
{\scriptscriptstyle\Pi}}}

\def\sum{\mathop{\mathchoice
{\yylopstyle\oldsum}
{\textstyle\oldsum}
{\scriptstyle\Sigma}
{\scriptscriptstyle\Sigma}}}

\def\Lm{\mathop{{\rm Lm}}}

\def\Col{\mathop{{\rm Col}}}

\def\Lub{\mathop{\mathchoice
{\yylopstyle\bigsqcup}
{\textstyle\bigsqcup}
{\raise-0.19355ex\hbox{$\mathsurround=0pt{\textstyle\sqcup}$}}
{\raise-0.13548ex\hbox{$\mathsurround=0pt{\scriptstyle\sqcup}$}}}}

\def\Glb{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
{\kern0.25pt
\vrule height10.53pt depth3.25pt width0.7pt
\vrule height10.53pt depth-9.83pt width8.25pt
\vrule height10.53pt depth3.25pt width0.7pt
\vrule height11.0pt depth5.0pt width0pt\kern1.2111pt}
\else {\setbox\yybxB=\hbox{\kern0.25pt
\vrule height8.37pt depth1.2pt width0.7pt
\vrule height8.37pt depth-7.67pt width5.5pt
\vrule height8.37pt depth1.2pt width0.7pt\kern1.18333pt}
\ht\yybxB=8.0pt\dp\yybxB=2.0pt\relax\box\yybxB}
\fi}
{{\setbox\yybxB=\hbox{\kern0.25pt
\vrule height8.37pt depth1.2pt width0.7pt
\vrule height8.37pt depth-7.67pt width5.5pt
\vrule height8.37pt depth1.2pt width0.7pt\kern1.18333pt}
\ht\yybxB=8.0pt\dp\yybxB=2.0pt\relax\box\yybxB}}
{{\raise-1pt\hbox{$\mathsurround=0pt{\textstyle\sqcap}$}}}
{{\raise-0.7pt\hbox{$\mathsurround=0pt{\scriptstyle\sqcap}$}}}}}

%Now we define two general macros for equiping operators with both limits
%and (sub- and super-) scripts.  \multscript prints limits below and above
%the operator and scripts to the right.  \compscript, which should be used
%when there is inadequate room for limits below and above, prints both
%limits and scripts to the right, with the limits further to the right.

%Both of these macros accepts two dimension parameters called the vertical
%and horizontal bulge, which are used to give the operator a larger size
%for the placement of limits and its relation to neighboring symbols
%than for the placement of scripts.  These parameters are given nonzero
%values for the circled operators defined in the next section.

%\multscript accepts the following parameters:
%   #1 - A main operator
%   #2 - a lower limit
%   #3 - an upper limit
%   #4 - a subscript
%   #5 - a superscript
%   #6 - a vertical bulge (a dimension)
%   #7 - a horizontal bulge (a dimension)
%   #8 - a style for the main operator
%   #9 - must be:
%           scriptstyle if #8 is displaystyle or textstyle
%           scriptscriptstyle if #8 is scriptstyle or scriptscriptstyle
%The result is a math operator with both limits (directly below and above
%the operator) and scripts (below and above and to the right of the
%operator).  If either limit is wider than the main operator, it will be
%lowered or raised to avoid overprinting the corresponding script.
%The vertical bulge is added to the height of the operator and to the depth
%of the operator in determining the position of the limits and the overall
%size of the result, but not in determining the position of the scripts.
%Kerns are added to the left and right of the final result so that it will
%have space on each side of the main operator at least equal to the horizontal
%bulge.  A script or limit is omitted if, when set in an hbox, it has width
%zero. Parameter #1 will be set in math mode, displaystyle (unless the
%style is changed within the parameter).  The result will be an ordinary
%math symbol, which the user may apply \mathop to.

\def\multscript#1#2#3#4#5#6#7#8#9{{
\setbox\yybxA=\hbox{$\mathsurround=0pt\mathop{{#1}}$}% main operator
\setbox\yybxB=\hbox{$\mathsurround=0pt#9{{#2}}$}% lower limit
\setbox\yybxC=\hbox{$\mathsurround=0pt#9{{#3}}$}% upper limit
\setbox\yybxD=\hbox{$\mathsurround=0pt#9{{#4}}$}% subscript
\setbox\yybxE=\hbox{$\mathsurround=0pt#9{{#5}}$}% superscript
\yydmA=\ht\yybxA% height of main operator
\yydmB=\dp\yybxA% depth of main operator
\yydmC=\yydmA\advance\yydmC by #6% height of main operator plus vertical bulge
\yydmD=\yydmB\advance\yydmD by #6% depth of main operator plus vertical bulge
\yydmE=\wd\yybxA% width of main operator
\yydmF=\yydmE\advance\yydmF by 0pt% maximum width of inner limits
\ht\yybxA=\yydmC\dp\yybxA=\yydmD% expand box to include vertical bulge
% main operator with inner limits
\setbox\yybxF=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxA}\limits
\ifdim\wd\yybxB=0pt\else\ifdim\wd\yybxB>\yydmF\else _{{#2}}\fi\fi
\ifdim\wd\yybxC=0pt\else\ifdim\wd\yybxC>\yydmF\else ^{{#3}}\fi\fi$}%
\yydmG=\ht\yybxF% height of main operator with inner limits
\yydmH=\dp\yybxF% depth of main operator with inner limits
\yydmI=\wd\yybxF% width of main operator with inner limits
\ht\yybxF=\yydmA\dp\yybxF=\yydmB% reduce to height and depth of main operator
% main operator with inner limits and scripts
\setbox\yybxG=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxF}\nolimits
\ifdim\wd\yybxD=0pt\else _{{#4}}\fi
\ifdim\wd\yybxE=0pt\else ^{{#5}}\fi
\vrule height\yydmC depth\yydmD width0pt$}%
\yydmA=\wd\yybxG% width of main operator with inner limits and scripts
\yydmB=\yydmE\advance\yydmB by -\yydmI\divide\yydmB by 2\relax
\advance\yydmB by #7\relax\ifdim\yydmB<0pt\yydmB=0pt\fi% left kern
\yydmC=\yydmB \advance \yydmC by \yydmI \advance\yydmC by -\yydmA% right kern
% main operator with all limits and scripts
\setbox\yybxD=\hbox{$\mathsurround=0pt#8\mathop
{\kern\yydmB\box\yybxG\kern\yydmC}\limits
\ifdim\wd\yybxB=0pt\else\ifdim\wd\yybxB>\yydmF _{{#2}}\fi\fi
\ifdim\wd\yybxC=0pt\else\ifdim\wd\yybxC>\yydmF ^{{#3}}\fi\fi$}%
\yydmD=\yydmI\advance\yydmD by \wd\yybxD\divide\yydmD by -2\relax
\advance\yydmD by \yydmA\relax\ifdim\yydmD<0pt\yydmD=0pt\fi% final right kern
\box\yybxD\kern\yydmD\vrule height\yydmG depth\yydmH width0pt}}

%The parameters of \compscript are the same as for \multscript.
%The result is a math operator with the scripts to the right of the
%operator and the limits as additional scripts further to the right.
%If only one limit is present it will be shifted left to immediately
%follow the corresponding script.  The vertical bulge is added to
%the height and depth of the main operator in determining the overall size
%of the result, but not the position of the scripts.  Kerns are added
%to the left and right of the final result so that it will have space on
%each side of the main operator at least equal to the horizontal bulge.
%A script or limit is omitted if, when set in an hbox, it has width
%zero. Parameter #1 will be set in math mode, displaystyle (unless the
%style is changed within the parameter).  The result will be an ordinary
%math symbol, which the user may apply \mathop to.

\def\compscript#1#2#3#4#5#6#7#8#9{{
\setbox\yybxA=\hbox{$\mathsurround=0pt\mathop{{#1}}$}% main operator
\setbox\yybxB=\hbox{$\mathsurround=0pt#9{{#2}}$}% lower limit
\setbox\yybxC=\hbox{$\mathsurround=0pt#9{{#3}}$}% upper limit
\setbox\yybxD=\hbox{$\mathsurround=0pt#9{{#4}}$}% subscript
\setbox\yybxE=\hbox{$\mathsurround=0pt#9{{#5}}$}% superscript
\yydmA=\ht\yybxA\advance\yydmA by #6% height of main op plus vertical bulge
\yydmB=\dp\yybxA\advance\yydmB by #6% depth of main op plus vertical bulge
\yydmC=\wd\yybxA% width of main operator
\yydmD=\wd\yybxE\advance\yydmD by -\wd\yybxD% overhang of super over subscript
%main operator with scripts
\setbox\yybxF=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxA}\nolimits
\ifdim\wd\yybxD=0pt\else _{{#4}}\fi
\ifdim\wd\yybxE=0pt\else ^{{#5}}\fi$}%
\yydmE=\wd\yybxF\relax% width of main operator with scripts
%main operator with scripts and limits
\ifdim\wd\yybxB=0pt\ifdim\wd\yybxC=0pt% no limits
\setbox\yybxG=\box\yybxF%
\else% upper limit but no lower limit
\setbox\yybxG=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxF
\ifdim\yydmD<0pt\kern\yydmD\else\fi}\nolimits ^{{#3}}$}%
\fi\else% lower limit
\ifdim\wd\yybxD=0pt\else\yydmF=\dp\yybxF
\advance\yydmF by 1pt\dp\yybxF=\yydmF\relax\fi
\ifdim\wd\yybxC=0pt% lower limit but no upper limit
\setbox\yybxG=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxF
\ifdim\yydmD>0pt\kern-\yydmD\else\fi}\nolimits _{{#2}}$}%
\else% both limits
\setbox\yybxG=\hbox{$\mathsurround=0pt#8\mathop{\box\yybxF
}\nolimits _{{#2}}^{{#3}}$}%
\fi\fi
\advance\yydmE by -\wd\yybxG%
\advance\yydmC by -\wd\yybxG\advance\yydmC by #7\relax%
\ifdim\yydmE<0pt\yydmE=0pt\else\fi\relax%
\ifdim\yydmC>\yydmE\yydmE=\yydmC\else\fi% final right kern
\kern #7\box\yybxG\kern\yydmE\vrule height\yydmA depth\yydmB width0pt}}

%The following macros produce specific math operators, with both limits
%and scripts, for product, sum, limit, colimit, least upper bound, and
%greatest lower bound.  They all accept the following parameters:
%   #1 - lower limit
%   #2 - upper limit
%   #3 - subscript
%   #4 - superscript
%These macros work for all four math styles, using the format of \multscript
%for display style and the format of \compscript for the remaining styles.

%For a call with vacuous scripts, such as \prodms{l}{u}{}{}, the result
%is essentially the same as \prod_{l}^{u}.  For a call with vacuous limits,
%such as \prodms{}{}{l}{u}, the result is essentially the same as
%\prod\nolimits_{l}^{u}.  In these cases, however, the calls of \...ms
%are much less efficient than those of the simpler macros.

\def\prodms#1#2#3#4{\mathop{\mathchoice
{\multscript{\yylopstyle\oldprod}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\yylopstyle}{\scriptstyle}}
{\compscript{\textstyle\oldprod}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript{\scriptstyle\Pi}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript{\scriptscriptstyle\Pi}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\summs#1#2#3#4{\mathop{\mathchoice
{\multscript{\yylopstyle\oldsum}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\yylopstyle}{\scriptstyle}}
{\compscript{\textstyle\oldsum}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript{\scriptstyle\Sigma}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript{\scriptscriptstyle\Sigma}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\Lmms#1#2#3#4{\mathop{\mathchoice
{\multscript{\displaystyle{\rm Lm}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\displaystyle}{\scriptstyle}}
{\compscript{\textstyle{\rm Lm}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript{\scriptstyle{\rm Lm}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript{\scriptscriptstyle{\rm Lm}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\Colms#1#2#3#4{\mathop{\mathchoice
{\multscript{\displaystyle{\rm Col}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\displaystyle}{\scriptstyle}}
{\compscript{\textstyle{\rm Col}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript{\scriptstyle{\rm Col}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript{\scriptscriptstyle{\rm Col}}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\Lubms#1#2#3#4{\mathop{\mathchoice
{\multscript{\yylopstyle\bigsqcup}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\yylopstyle}{\scriptstyle}}
{\compscript{\textstyle\bigsqcup}{#1}{#2}{#3}{#4}
{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\raise-0.19355ex\hbox{$\mathsurround=0pt{\textstyle\sqcup}$}}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\raise-0.13548ex\hbox{$\mathsurround=0pt{\scriptstyle\sqcup}$}}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\Glbms#1#2#3#4{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
\multscript{\kern0.25pt
\vrule height10.53pt depth3.25pt width0.7pt
\vrule height10.53pt depth-9.83pt width8.25pt
\vrule height10.53pt depth3.25pt width0.7pt
\vrule height11.0pt depth5.0pt width0pt\kern1.2111pt}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\displaystyle}{\scriptstyle}
\else \multscript{\setbox\yybxB=\hbox{\kern0.25pt
\vrule height8.37pt depth1.2pt width0.7pt
\vrule height8.37pt depth-7.67pt width5.5pt
\vrule height8.37pt depth1.2pt width0.7pt\kern1.18333pt}
\ht\yybxB=8.0pt\dp\yybxB=2.0pt\relax\box\yybxB}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\textstyle}{\scriptstyle}\fi}
{\compscript{\setbox\yybxB=\hbox{\kern0.25pt
\vrule height8.37pt depth1.2pt width0.7pt
\vrule height8.37pt depth-7.67pt width5.5pt
\vrule height8.37pt depth1.2pt width0.7pt\kern1.18333pt}
\ht\yybxB=8.0pt\dp\yybxB=2.0pt\relax\box\yybxB}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\raise-1pt\hbox{$\mathsurround=0pt{\textstyle\sqcap}$}}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\raise-0.7pt\hbox{$\mathsurround=0pt{\scriptstyle\sqcap}$}}
{#1}{#2}{#3}{#4}{0pt}{0pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}


%CIRCLED OPERATORS

%Here we define macros that produce circled versions of the large operators
%for product, sum (coproduct), limit, and colimit.  These symbols are used
%for unique mediating morphisms.

%FONT DEPENDENCY:  The circled-operator macros are all specific to
%computer modern font in 12pt style.

%First, we define a general macro \encircle for enclosing an expression
%in a circle.  \encircle accepts:
%   #1 - an x-coordinate
%   #2 - a y-coordinate
%   #3 - a diameter
%   #4 - any expression
%It uses the LATEX circle-drawing facility to produce an expression
%similar to #4 but overlaid by a circle of the specified diameter
%whose center is specified by the coordinates, relative to the
%reference point of the expression.  The size of the expression
%is unchanged.  Parameters #1 to #3 are integers, representing
%dimensions in tenths of a point.  Circles are available with the
%following diameters: 400, 360, 320, 280, 240, 200, 160, 150, 140,
%130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10.

\def\encircle#1#2#3#4{\setlength{\unitlength}{0.1pt}
\begin{picture}(0,0)
\put(#1,#2){\circle{#3}}
\end{picture}
{#4}}

%Then we define four macros for the specific circled operators.  These
%macros are used in the same way as the multiple-script macros in the
%previous section, and produce results with similar appearance, except
%that the main operator is enlarged by enclosing it in a circle.
%For example, \cirprodmsnorm corresponds to \prodms.

\def\cirprodmsnorm#1#2#3#4{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
\multscript
{\kern3.5pt\encircle{59}{34}{200}{\displaystyle\oldprod}\kern3.5pt}
{#1}{#2}{#3}{#4}{2.5pt}{0.5pt}{\displaystyle}{\scriptstyle}
\else \multscript
{\kern2.5pt\encircle{42}{34}{140}{\textstyle\oldprod}\kern2.5pt}
{#1}{#2}{#3}{#4}{2.0pt}{0pt}{\textstyle}{\scriptstyle}\fi}
{\compscript
{\kern2.5pt\encircle{42}{34}{140}{\textstyle\oldprod}\kern2.5pt}
{#1}{#2}{#3}{#4}{1.5pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.75pt\encircle{31}{27}{90}{\scriptstyle\Pi}\kern1.75pt}
{#1}{#2}{#3}{#4}{1pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1pt\encircle{23}{20}{70}{\scriptscriptstyle\Pi}\kern1pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.25pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirsummsnorm#1#2#3#4{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
\multscript
{\kern2.5pt\encircle{65}{33}{200}{\displaystyle\oldsum}\kern2.5pt}
{#1}{#2}{#3}{#4}{2.5pt}{1.0pt}{\displaystyle}{\scriptstyle}
\else \multscript
{\kern2.5pt\encircle{47}{34}{150}{\textstyle\oldsum}\kern2.5pt}
{#1}{#2}{#3}{#4}{2.75pt}{0pt}{\textstyle}{\scriptstyle}\fi}
{\compscript
{\kern2.5pt\encircle{47}{34}{150}{\textstyle\oldsum}\kern2.5pt}
{#1}{#2}{#3}{#4}{2.25pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.25pt\encircle{27}{28}{80}{\scriptstyle\Sigma}\kern1.25pt}
{#1}{#2}{#3}{#4}{1pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1.25pt\encircle{25}{19}{70}{\scriptscriptstyle\Sigma}\kern1.25pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.5pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirLmmsnorm#1#2#3#4{\mathop{\mathchoice
{\multscript
{\kern2pt\encircle{87}{37}{200}{\textstyle{\rm Lm}}\kern2pt}
{#1}{#2}{#3}{#4}{6pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern2pt\encircle{87}{37}{200}{\textstyle{\rm Lm}}\kern2pt}
{#1}{#2}{#3}{#4}{6pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.5pt\encircle{61}{27}{140}{\scriptstyle{\rm Lm}}\kern1.5pt}
{#1}{#2}{#3}{#4}{3.5pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1pt\encircle{51}{20}{120}{\scriptscriptstyle{\rm Lm}}\kern1pt}
{#1}{#2}{#3}{#4}{3pt}{0.3pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirColmsnorm#1#2#3#4{\mathop{\mathchoice
{\multscript
{\kern2pt\encircle{93}{35}{200}{\textstyle{\rm Col}}\kern2pt}
{#1}{#2}{#3}{#4}{6.25pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern2pt\encircle{93}{35}{200}{\textstyle{\rm Col}}\kern2pt}
{#1}{#2}{#3}{#4}{6.25pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.5pt\encircle{65}{24}{140}{\scriptstyle{\rm Col}}\kern1.5pt}
{#1}{#2}{#3}{#4}{4pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1.25pt\encircle{57}{21}{130}{\scriptscriptstyle{\rm Col}}\kern1.25pt}
{#1}{#2}{#3}{#4}{3.5pt}{0.5pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

%Next we define four analogous macros that produce ``shrunken versions''
%of the circled operators.  For example, \cirprodmsshrunk gives a circled
%product operator such that the size of the enclosing circle is about
%the same as the size of the uncircled operator given by \prodms.

\def\cirprodmsshrunk#1#2#3#4{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
\multscript
{\kern2.25pt\raise0.2pt\hbox{$\mathsurround=0pt\encircle{43}{35}{150}
{\textstyle\oldprod}$}
\vrule height11.0pt depth5.0pt width0pt\kern2.25pt}
{#1}{#2}{#3}{#4}{0pt}{1.5pt}{\displaystyle}{\scriptstyle}
\else \multscript
{\kern1.75pt\raise-0.6pt\hbox{$\mathsurround=0pt\encircle{42}{41}{120}
{\textstyle\Pi}$}
\vrule height8.0pt depth2.0pt width0pt\kern1.75pt}
{#1}{#2}{#3}{#4}{1.0pt}{0.5pt}{\textstyle}{\scriptstyle}\fi}
{\compscript
{\kern1.75pt\raise-0.6pt\hbox{$\mathsurround=0pt\encircle{42}{41}{120}
{\textstyle\Pi}$}
\vrule height8.0pt depth2.0pt width0pt\kern1.75pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.5pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1pt\raise0.6875pt\hbox{$\mathsurround=0pt\encircle{23}{20}{70}
{\scriptscriptstyle\Pi}$}
\vrule height5.47221pt depth0pt width0pt\kern1pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1pt\encircle{23}{20}{70}{\scriptscriptstyle\Pi}\kern1pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.25pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirsummsshrunk#1#2#3#4{\mathop{\mathchoice
{\ifnum\yylopstyleswitch=1\relax
\multscript
{\kern1.75pt\raise0.2pt\hbox{$\mathsurround=0pt\encircle{47}{34}{150}
{\textstyle\oldsum}$}
\vrule height11.0pt depth5.0pt width0pt\kern1.75pt}
{#1}{#2}{#3}{#4}{0pt}{1.5pt}{\displaystyle}{\scriptstyle}
\else \multscript
{\kern2.0pt\raise-0.6pt\hbox{$\mathsurround=0pt\encircle{38}{41}{120}
{\textstyle\Sigma}$}
\vrule height8.0pt depth2.0pt width0pt\kern2.0pt}
{#1}{#2}{#3}{#4}{1.25pt}{0.5pt}{\textstyle}{\scriptstyle}\fi}
{\compscript
{\kern2.0pt\raise-0.6pt\hbox{$\mathsurround=0pt\encircle{38}{41}{120}
{\textstyle\Sigma}$}
\vrule height8.0pt depth2.0pt width0pt\kern2.0pt}
{#1}{#2}{#3}{#4}{0.75pt}{0.5pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.5pt\raise0.6875pt\hbox{$\mathsurround=0pt\encircle{25}{19}{70}
{\scriptscriptstyle\Sigma}$}
\vrule height5.47221pt depth0pt width0pt\kern1.5pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.3pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1.25pt\encircle{25}{19}{70}{\scriptscriptstyle\Sigma}\kern1.25pt}
{#1}{#2}{#3}{#4}{0.5pt}{0.5pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirLmmsshrunk#1#2#3#4{\mathop{\mathchoice
{\multscript
{\kern1.5pt\raise1.36pt\hbox{$\mathsurround=0pt\encircle{61}{27}{140}
{\scriptstyle{\rm Lm}}$}
\vrule height8.2pt depth0pt width0pt\kern1.5pt}
{#1}{#2}{#3}{#4}{3pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.5pt\raise1.36pt\hbox{$\mathsurround=0pt\encircle{61}{27}{140}
{\scriptstyle{\rm Lm}}$}
\vrule height8.2pt depth0pt width0pt\kern1.5pt}
{#1}{#2}{#3}{#4}{3pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.25pt\raise0.90pt\hbox{$\mathsurround=0pt\encircle{51}{20}{120}
{\scriptscriptstyle{\rm Lm}}$}
\vrule height5.47221pt depth0pt width0pt\kern1.25pt}
{#1}{#2}{#3}{#4}{2.5pt}{0.5pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1pt\encircle{51}{20}{120}{\scriptscriptstyle{\rm Lm}}\kern1pt}
{#1}{#2}{#3}{#4}{3pt}{0.3pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

\def\cirColmsshrunk#1#2#3#4{\mathop{\mathchoice
{\multscript
{\kern2pt\raise1.00pt\hbox{$\mathsurround=0pt\encircle{66}{26}{150}
{\scriptstyle{\rm Col}}$}
\vrule height8.33333pt depth0pt width0pt\kern2pt}
{#1}{#2}{#3}{#4}{3.5pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern2pt\raise1.00pt\hbox{$\mathsurround=0pt\encircle{66}{26}{150}
{\scriptstyle{\rm Col}}$}
\vrule height8.33333pt depth0pt width0pt\kern2pt}
{#1}{#2}{#3}{#4}{3.5pt}{0pt}{\textstyle}{\scriptstyle}}
{\compscript
{\kern1.5pt\raise0.68pt\hbox{$\mathsurround=0pt\encircle{57}{21}{130}
{\scriptscriptstyle{\rm Col}}$}
\vrule height5.55556pt depth0pt width0pt\kern1.5pt}
{#1}{#2}{#3}{#4}{2.75pt}{0.75pt}{\scriptstyle}{\scriptscriptstyle}}
{\compscript
{\kern1.25pt\encircle{57}{21}{130}{\scriptscriptstyle{\rm Col}}\kern1.25pt}
{#1}{#2}{#3}{#4}{3.5pt}{0.5pt}{\scriptscriptstyle}{\scriptscriptstyle}}}}

%Finally we define four macros, \cirprodms, \cirsumms, \cirLmms, and
%\cirColms, that give circled operators for which the size is determined
%by declarations.  Following a call of \largecircleops (to the end of the
%enclosing group), these macros will give normal sized operators.
%Following a call of \smallcircleops (to the end of the enclosing group),
%these macros will give shrunken operators.  The default is normal size.

%Note that the size of these operators in display style is also affected
%by \compresslargeops and \expandlargeops.

\def\largecircleops{
\let\cirprodms=\cirprodmsnorm
\let\cirsumms=\cirsummsnorm
\let\cirLmms=\cirLmmsnorm
\let\cirColms=\cirColmsnorm}

\def\smallcircleops{
\let\cirprodms=\cirprodmsshrunk
\let\cirsumms=\cirsummsshrunk
\let\cirLmms=\cirLmmsshrunk
\let\cirColms=\cirColmsshrunk}

\largecircleops

