Commutative Diagrams in TEX

Paul Taylor Department of Computing, Imperial College of Science, Technology and Medicine, 180 Queen’s Gate, London SW7 2BZ +44 71 589 5111 ext. 5057

                          <pt@doc.ic.ac.uk>

4 July 1990

Abstract

TEX and LaTEX have become standard as a way of writing papers in Computer Science, and are being adopted in Category Theory. Even in source form they are easier to compose and read than attempts to write mathematics in ASCII. In Category Theory “commutative diagrams” are essential for a clear visual understanding of the paper, but the graphics capabilities of TEX are so limited that it is very difficult to draw them nicely, if at all. This manual describes some methods which have been used for doing so, criticising them for either their source syntax or for the printed result (“semantics”), and sets out design criteria. Then the author’s package is described, with examples.

1 Introduction

In papers in mathematics and computer science which employ Category Theory, there is much benefit in clarity if “commutative diagrams” are used as much as possible to illustrate definitions, equations and universal properties. Here is a typical such diagram: it is one of the Mac Lane-Kelly equations.

[figure: A ∗ (B ∗ (C ∗ D)); (A ∗ B) ∗ (C ∗ D); ((A ∗ B) ∗ C) ∗ D; A ∗ ((B ∗ C) ∗ D); (A ∗ (B ∗ C)) ∗ D; id ∗ assl; assl ∗ id; assl; assl; assl; =]

The majority of such diagrams are rectangular, although triangles are often required, and sometimes we need to depict a “cube.”

1.1 LaTEX pictures

For LaTEX^{1} users, an obvious approach to this problem is to use the picture environment. For instance, in his paper The Linear Abstract Machine, Yves Lafont produced the diagram above as follows:

\newcommand\object[1] {\makebox(0,0)[c]{$#1$}}

1But I usually use plain TEX, so it is one of my design criteria that the package work with both LaTEX and plain TEX.

\newcommand\Id{{\rm id}}}
\newcommand\Assl{{\rm assl}}
\begin{center}
\setlength \unitlength {0.25em}
\begin{picture}(150,30)(-75,-15)
\put(-60,  6){\vector(0,-1){12}}
\put( 60, -6){\vector(0,1){12}}
\put(-40, 10){\vector(1,0){20}}
\put( 20, 10){\vector(1,0){20}}
\put(-40,-10){\vector(1,0){80}}
\put(-60, 10){\object{A * (B * (C * D))}}
\put(  0, 10){\object{(A * B) * (C * D)}}
\put( 60, 10){\object{((A * B) * C) * D}}
\put(-60,-10){\object{A * ((B * C) * D)}}
\put( 60,-10){\object{(A * (B * C)) * D}}
\put(-50,  0){\object{\Id * \Assl}}
\put( 50,  0){\object{\Assl * \Id}}
\put(-30, 13){\object{\Assl}}
\put( 30, 13){\object{\Assl}}
\put(  0, -7){\object{\Assl}}
\put(  0,  0){\object{=}}
\end{picture}
\end{center}

Of course the co-ordinates of the arrow labels are dependent on those of the arrows themselves, so it would not be difficult to package the \vector command with an additional argument for the label, and also provide variants for tailed and double-headed arrows (for monos and epis).

It is true that the majority of the diagrams one needs are just squares and triangles, so an alternative approach would be to write a collection of macros which would fill in labels in standard diagrams. For instance, for their book Category Theory for Computing Science^{2}, Michael Barr and Charles Wells created a package called catmac^{3} which produces a square essentially with the command

                               \square[A‘B‘C‘D; f‘g‘h‘k]

However the extended example which they give uses 32 lines of code (including at least 60 specified distances and numerous \phantoms, i.e. text printed in white ink) to describe 12 objects, 15 labelled arrows and 7 cells. The code is therefore more difficult to follow and shorter than our first bare-hands approach.

However one attempts to simplify this, it remains necessary to draw each diagram individually on graph paper before typing it in this opaque notation. This is a serious dis-incentive to the author to use diagrams, whereas Barr and Wells’ book itself shows how much clearer Category Theory becomes when they are used.

Francis Borceux’s package^{4} is also based on LaTEX pictures, but the need to quote co-ordinates is eliminated by use of a standard grid: objects and arrows are placed at the “current” position, with commands to advance by columns and rows. A variety of arrows is provided, with systematic names.

2Prentice-Hall, 1990, ISBN 0-13-120486-6

3Available from Mike Barr at Mc Gill University, Montreal, <barr@gauss.math.mcgill.ca>, <inhb@musicb.mcgill.ca> or <inhb@mcgillb.bitnet>. BITNET is not recommended because it corrupts important characters.

4Université Catholique de Louvain-la-Neuve, Belgium: <Borceux@buclln11.bitnet>

A LaTEX user may consider that the picture environment provides the basis for a general package, but LaTEX was never designed to be used in this way. It provides excellent facilities for global management of documents which TEX does not supply, but the popularity of the picture environment is way out of proportion to the facilities actually provided or the amount of code (200 lines or 10kb without comments) involved. As a programming language it also effectively deprives the user of those few but useful programming primitives which TEX has. LaTEX documents, and even more so LaTEX programs, are therefore characterised by verbosity and awkward syntax: compare our

                                ... X & \rTo^f & Y...

with Borceux’s

                           ... {X} \n {\Ear{f}} \n {Y}...

Let me say, however, to be fair, that if I had had LaTEX and Francis Borceux’s package available when I first started using TEX, I would never have gone to the trouble of programming the package described in this paper.

1.2 TEXercise 18.46

Considering the fact that most diagrams are essentially rectangular arrays, they carry with them an “intrinsic” co-ordinate system given by the cell structure. Borceux has already exploited this fact, but his cells are translated directly into co-ordinates and so are forced to be the same size. However in general the cells may be of different widths and heights depending on the sizes of the object and morphism labels. This adjustment is something which should be the responsibility of the diagram package, not of the user.

A simple solution^{5} to these problems was provided by Donald Knuth in The TEXbook. Notice that the “co-ordinate system” adopted places each object and each morphism in a separate cell, rather than using the “categorical 2-cells” which Mike Barr seems to have had in mind.

\newcommand\rTo[1]{\smash{\mathop{\longrightarrow}\limits^{#1}}}
\newcommand\lTo[1]{\smash{\mathop{\longleftarrow}\limits^{#1}}}
\newcommand\dTo[1]{\Big\downarrow\rlap{$\vcenter{\hbox{$\scriptstyle#1$}}$}}
\newcommand\uTo[1]{\Big\uparrow\rlap{$\vcenter{\hbox{$\scriptstyle#1$}}$}}
\newenvironment{diagram}%
   {\renewcommand{\arraystretch}{2}\begin{array}{*{20}{c}}}%
   {\end{array}}

$$\begin{diagram}

      A*(B*(C*D))  &\rTo{\Assl}&(A*B)*(C*D)&\rTo{\Assl}&  ((A*B)*C)*D  \\
    \dTo{\Id*\Assl}&            &     =     &            &\uTo{\Assl*\Id}\\
      A*((B*C)*D)  &            &\rTo{\Assl}&            &  (A*(B*C))*D  \\

\end{diagram}$$

which produces the following result:

5I have partly translated it into LaTEX but it is still necessary to descend to the TEX level to define the commands.

A ∗ (B ∗ (C ∗ D)) ⟶^{assl} (A ∗ B) ∗ (C ∗ D) ⟶^{assl} ((A ∗ B) ∗ C) ∗ D
↓^{id∗assl}  =  ↑^{assl∗id}
A ∗ ((B ∗ C) ∗ D)  ⟶^{assl}  (A ∗ (B ∗ C)) ∗ D

Already we can see a very great improvement, in particular • the LaTEX source is set out in the same way as the intended diagram, and

• there are no co-ordinates.

1.3 AMS-TEX

In AMS-TEX this is developed and using the code

$$\CD

      A*(B*(C*D))   @>\Assl>>  (A*B)*(C*D)  @>\Assl>>   ((A*B)*C)*D  \\
     @V\Id*\AsslVV                  =     &          &@AA\Assl*\Id A\\
      A*((B*C)*D) &            @>\Assl>> &             (A*(B*C))*D  \\

\endCD$$

we can get

A ∗ (B ∗ (C ∗ D)) ⟶^{assl} (A ∗ B) ∗ (C ∗ D) ⟶^{assl} ((A ∗ B) ∗ C) ∗ D
id∗assl↓  =  ↑^{assl∗id}
A ∗ ((B ∗ C) ∗ D)  ⟶^{assl}  (A ∗ (B ∗ C)) ∗ D

This is better than Knuth’s version in that

• the arrows will stretch to fit their labels (this is done simply by replacing

  \longrightarrow with \rightarrowfill),

• there is an interesting syntactic^{6} idea using @>f>g> to produce the two labels, and • the column delimiters (&) are implicit in the arrows.

However,

• if the label on one arrow in a column is larger than another, the arrows will be of different lengths. Although a hack is provided to overcome this: \pretend f \haswidth{long label}, the arrows can only stretch as far as the edge of the enclosing cell, so in the case of objects of different lengths we still get gaps.

• the implicit column delimiters don’t work, as you see,

• the label on the lower arrow causes the vertical arrows to fall short of their endpoints, and

• there is no provision for different arrowheads or for diagonals.

6A simplified extract from AMS-TEX is included in the source of this document, but this feature has been omitted.

1.4 Postscript pictures

TEX and LaTEX users will already be aware of the wysiwyg^{7} fallacy. Nevertheless the suggestion is frequently made that the best way to solve this problem would be to “draw it on the screen.” Given that, by hypothesis, we are using TEX or LaTEX and not a Mac^{8} to compose the text of the document, let us consider the implications of using the latter to draw just the diagrams.

• The positioning of the object and morphism labels is part of the same problem as the calculation of the lengths of the arrows, so these labels must be inserted on the Mac too, using its fonts and not enjoying the advantages of uniform TEX definitions.

• Bringing the diagrams and the text together either involves physical scissors-and-paste or requires a dvi driver which translates into Postscript. There are plenty of high-resolution printers around which are capable of printing dvi documents without using Postscript — and they’re faster, too! Even those drivers which can incorporate Postscript are mutually incompatible.

• For each diagram in the document you need a separate Postscript file (a recent 30-page paper of mine contained 68 diagrams). Drawing each of the diagrams separately and down-loading them from a Mac to Unix would be very time-consuming, and keeping all of these files together would make the source of the document very unwieldy.

• Alternatively, you could incorporate Postscript directly into the TEX source via a \special command. Though more manageable, this is still not portable. Now that you’re no longer using a Mac to draw the pictures, it’s just as difficult to do this as programming the problem in TEX in the first place.

• The missing features of TEX, notably diagonal lines, could be added by (low-level) use of embedded PostsScript in \specials. The results would be superior, but portability would be lost.

1.5 Design Criteria

Having studied several partial solutions to the problem, we now set out our basic design criteria.

1. There must be no preprocessing (cf. eqn in Unix) or inclusion of files (such as Postscript pictures inserted using \special commands): the entire diagram must form part of the source of the document itself.

2. Simple diagrams must be able to be drawn “on the fly” and not need to be drawn on paper first (although obviously complex diagrams will already have been worked out on paper anyway).

3. The layout of the source code must resemble the intended diagram as far as syntactically possible.

4. There must be no measuring of labels to calculate co-ordinates or lengths of arrows.

5. There must be a variety of arrow styles, with facilities for defining new ones. Diagonal arrows should be provided at various slopes, albeit with limited choice and features.

7“What you see is what you get.”

8The words in Small Capitals are trade marks.

6. The package must be compatible both with plain TEX and with LaTEX, and not rely on non-standard fonts^{9} or language features.

7. Future versions which improve the appearance of the diagrams should be compatible with past papers written using the package (but you hack at your own risk).

In addition there are æsthetic criteria, some of which may be a matter of opinion:

• Arrows should stretch to meet the objects which are intended to be their endpoints.

• Arrows should be aligned (both horizontally and vertically) with the centres of the objects.

• Labels on arrows should not affect the spacing of the diagram except to avoid overlapping.

• Stretching of arrows should not affect the centering of their labels.

2 User Manual

My version of the diagram is produced as follows:

\input diagrams
$$\begin{diagram}

      A*(B*(C*D))   &\rTo^\Assl&(A*B)*(C*D)&\rTo^\Assl&   ((A*B)*C)*D   \\
    \dTo^{\Id*\Assl}&           &     =     &           &\uTo_{\Assl*\Id}\\
      A*((B*C)*D)   &           & \rTo^\Assl &           &   (A*(B*C))*D   \\

\end{diagram}$$

which yields

A ∗ (B ∗ (C ∗ D)) \overline{assl}\overline{>} (A ∗ B) ∗ (C ∗ D) \overline{assl}\overline{>} ((A ∗ B) ∗ C) ∗ D ∧
id ∗ assl∨  =  assl ∗ id

A ∗ ((B ∗ C) ∗ D)  \overline{assl}  \overline{>} (A ∗ (B ∗ C)) ∗ D

As you see, it is based on Knuth’s version but does not adopt AMS-TEX’s confusing attempts to eliminate &s. It also stretches the arrows to meet the objects.

2.1 Typing the diagram

The basic rule is to divide the diagram into cells:

\begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}
A ∗ (B ∗ (C ∗ D)) \overline{assl} \overline{>} (A ∗ B) ∗ (C ∗ D) \overline{assl} \overline{>} ((A ∗ B) ∗ C) ∗ D
····························································································· ∧
id ∗ assl∨  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  =  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  assl ∗ id
·····························································································
A ∗ ((B ∗ C) ∗ D)  \overline{assl}  \overline{>} (A ∗ (B ∗ C)) ∗ D

9Diagonal lines can only be drawn using LaTEX’s line10 and linew10 fonts, and for exotic arrow styles the AMS maths symbols fonts may be useful: we regard these as standard.

just like the cells of a matrix, and then type the contents of the cells with columns delimited by “&” and rows by “\\”. The bottom arrow extends through the empty cells either side of it. Notice that although the matrix imposes a kind of co-ordinate system, the widths of the columns and the heights of the rows are variable and chosen automatically (by TEX, in the same way as it does for matrices, tables, etc.)

Each cell should contain either an object (an ordinary mathematical expression, set in maths mode) or a morphism (an arrow such as \rTo^f). Horizontal and vertical arrows cannot be mixed in one cell, and only one horizontal arrow per cell is allowed (but see the section on parallel maps below).

Likewise, re-alignment of objects using \hfil is likely to fail since objects end up being set in an \hbox to their natural width (and height).

Do not enclose the arrow commands in boxes or braces, because this also prevents the automatic stretching from working.

Every morphism must have an object at each end to terminate it: it must not meet another morphism or extend off the edge of the diagram. If you want to use the arrow commands for other lines without objects to terminate them (this is how the above diagram with dotted cells was drawn), then the object position must be occupied by a space command such as \; or by something else that produces an object but does not print, such as {} or \null. Even \relax or \empty would do, so long as there’s something other than white space (or comments) between successive &s. If you forget to terminate an arrow, part or all of it will be lost.

Any LaTEX environment, say \begin{env}...\end{env}, is just a packaged way of invoking the commands \env and \endenv^{10}, so for plain TEX you just use \diagram...\enddiagram instead. There is also a command \commdiag with an argument, but this is only included for reverse compatibility. Of course LaTEX users can also substitute \[...\] or

begin{displaymath}...\end{displaymath} for $$...$$.

 $$
 \diagram
    ...
 \enddiagram
 $$

needed for TEX or

                     $$
                     \commdiag{
                        ...
                     }
                     $$

obsolete or

                                      \begin{displaymath}
                                      \begin{diagram}
                                         ...
                                      \end{diagram}
                                      \end{displaymath}

LaTEX only or

                                                                 \[
                                                                 \begin{diagram}
                                                                   ...
                                                                 \end{diagram}
                                                                 \]

LaTEX only

The horizontal arrow commands may also be used in text, A ^{f} > B. Since there is no enclosing matrix, this is written as $A \rTo^f B$ without &.

Arrows may be made to come right up to the objects by using the \MapsAbut command; this is in fact an abbreviation for \MapShortFall=0pt which sets the actual amount of space at the ends of the arrows (default 0.4em). Individual arrows may be altered in this way by using this command inside a cell.

Each cell in the diagram is forced to be at least \DiagramCellWidth wide and \DiagramCellHeight high^{11}. The default values are 3em, which allows for objects of width “MMM”; if they’re wider or narrower, the best way to adjust the size of the diagram is by using the command \CellSize=5em which changes both parameters together.

10There is also an extra level of grouping, and LaTEX checks that the the same environment type occurs at the beginning and the end.

11Actually, height plus depth

2.2 Labels

Each arrow potentially carries two labels, called leading and trailing, which are given like superscripts and subscripts^{12} respectively. For reverse compatibility, there may instead be two positional arguments, which must be enclosed in braces, e.g. \rTo{f}{g} but not \rTo f g. The arrow commands are fragile in the LaTEX sense: they cannot, for instance, be used in footnotes.

The rule for positioning the labels is

• for horizontal arrows, \rTo^f_g and \rTo\{f\}\{g\} give \begin{matrix}f \\ g \end{matrix} > ;

• for vertical arrows, \dTo^f_g and \dTo{f}{g} give f↓g;

• for diagonal arrows, \SW^f_g and \SW{f}{g} put f above and g below.

• Using tilde, the label may instead break the arrow \rTo~f gives

A  \overline{f} \overline{>} B

Although the arrows extend into adjacent cells, the labels remain centred in the cell in which the arrow was declared.

Any ordinary (mathematical) text you put in the cell with an arrow will appear in the usual way. For horizontal arrows it will therefore be attached to the arrowhead/tail, whilst for vertical and diagonal arrows it will lie to the side of (or between) the arrows. However if you want to put a superscript on the arrow-head you should define a new arrow command: section 2.4 explains how to do this.

By default the labels on the arrows are set in \textstyle (the same size as in text) when they are part of a matrix, and in \scriptstyle (like subscripts) in text. However this may be changed by re-defining the command \labelstyle, for instance

\begin{displaymath}
\renewcommand\labelstyle{\displaystyle}
\begin{diagram}
A &\rTo^{\sum^n_1 f_i}_{\rm display} & B
\end{diagram}
\qquad
...
\end{displaymath}

gives

A \overline{\begin{matrix}∑_{1}^{n} f_{i} \\ display \end{matrix}} \overline{>} B  A \overline{\begin{matrix}∑_{1}^{n} f_{i} \\ text \end{matrix}} \overline{>} B  A \overline{\begin{matrix}∑_{1}^{n} f_{i} \\ script \end{matrix}} \overline{>} B  A \overline{∑{n \atop 1} f_{i} scriptscript}\overline{>} B

Similarly, objects are set in \displaystyle unless the \objectstyle command is redefined.

12However they are not recognised syntactically in the same way, and so for instance \nolimits will not work.

2.3 Arrow styles currently available

The following arrow styles are available, annotated with their names as the leading (first, upper, superscript or left-hand) argument, e.g. \rTo^{\tt rTo}. The arrows are made up of juxtaposed pieces, as explained in the next section. Please note that good alignment depends to a large extent on having an accurate dvi driver, which most are not. Wherever possible, the arrows have been designed to be tolerant of inaccuracies, but this is difficult to achieve, although it may improve with future versions. Some of the arrows have synonyms such as \lFrom for reverse compatibility.

A \overline{\rTo}  \overline{>} B ∧

         \uTo  \dTo∨

C < \lTo D

A ············ \begin{matrix}\rDotsto \\ · \end{matrix} ············ > B \begin{matrix}∧ \\ · \\ · \\ · \\ · \\ · \\ · \end{matrix}  \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \end{matrix}
\uDotsto\begin{matrix}· \\ · \\ · \\ · \\ · \\ · \end{matrix}  \dDotsto\begin{matrix}· \\ · \\ · \\ · \\ · \\ · \\ ∨ \end{matrix}

C < ············ \begin{matrix}\lDotsto \\ · \end{matrix} ············ D

             A \overline{\rArr}  \overline{}B

         \uArr  \dArr

             C ^{\lArr}  D

                                                    A  \overline{\rOnto}  \overline{}B ↑ ↑
                                              \uOnto  \dOnto↓ ↓

                                                    C  \lOnto  D

A = \rImplies \begin{matrix}= \\ = \\ = \\ = \\ = \\ = \\ = \\ = \\ = \\ ⇒ \end{matrix} B \begin{matrix}⇑ \\ ∥ \\ ∥ \end{matrix}  ∥

\uImplies∥  \dImplies∥ ⇓

C ⟸ \lImplies = = = = = = = = = = D

                                                       A  \rMapsto    \overline{>} B ∧
                                               \uMapsto  \dMapsto∨

                                                      C < \lMapsto  D

          A ^{_{⊂} \rIntoA}   \overline{>} B ∧  ∩
   \uIntoA ∪  \dIntoA∨

          C < \lIntoA    \overline{⊃} D

                                                     A _{⊂} \rIntoB   \overline{>} B ∧  ∩
                                               \uIntoB∪  \dIntoB∨

                                                     C < \lIntoB    \overline{⊃} D

       A > \rEmbed   \overline{>} B ∧  ∨
\uEmbed∧  \dEmbed∨

       C < \lEmbed   \overline{<} D

                                                   A  \overline{\rProject}     \overline{▷} B

△

                                          \uProject  \dProject

                                                   C ◁  \lProject  D

A ············ \begin{matrix}\hDots \\ · \end{matrix} ··········· B \begin{matrix}· \\ · \\ · \\ · \\ · \\ · \end{matrix}

    \vDashes  \vDots\begin{matrix}· \\ · \\ · \\ · \\ · \\ · \end{matrix}

           C  \hDashes  D

A = \hEq = = = = = = = B ∥

                                                   \vEq∥  \vLine

                                                       C \overline{\hLine}  D

           A  \rDashto > B

∧

   \uDashto  \dDashto∨

           C < \lDashto  D

                                                         A \overline{\rPto}  \overline{⇀} B

                                                    \uPto  \dPto

                                                         C ↼ \lPto  D

A

                                   [figure: \NE; \SE]

D  B

                                    [figure: \NW; \SW]

C

2.4 Defining additional arrows

The arrow commands such as \rTo are defined in a systematic way from five parts. From left to right or top to bottom, these are:

leading tip, first filler, middle, second filler, trailing tip

The tips and middle are arrowheads, hooks, etc. of fixed sizes, whilst the fillers are repeatable line-segments. This is just like TEX’s expandable brackets.

For example,

\newcommand\rCrossedInto{\HorizontalMap \rthooka - + - \rhvee }
$$\begin{diagram}
  A &  \rCrossedInto^f  & B \cr
\end{diagram}$$

produces

A ^{⊂}  \begin{matrix}f \\ + \end{matrix} \overline{>} B

and similarly for \VerticalMap. Unlike the optional labels, the five arguments are mandatory; null arguments must be given as {} or \empty.

Some symbols may be used directly as bits of arrows, whilst others need to be moved into the correct positions. For instance “>” (greater than) makes a good arrow-tail but is not suitable as a head because the shaft of the arrow would not join up with its point. In these cases it is better to define a new symbol (e.g. \rhvee) for use as part of an arrow.

The obvious symbols

−, =, \equiv (≡), | and \| (∥)

are suitable as horizontal and vertical fillers. The single lines (- and |) are treated as special cases: a rule is produced instead of a repeating symbol. The extra symbols

                      \hfdot, \vfdot, \hfdash and \vfdash

can be used for horizontal and vertical dotted and dashed lines. Repeating symbols are overlapped slightly to ensure a good join; this also makes them stick out at the end, so the same symbol should also be used as a tail if otherwise there would be none. It is also a good idea to repeat dots and dashes as middles to ensure regularity.

The arrows

   ← \leftarrow ⇐ \Leftarrow ↼ \leftharpoonup  ↽ \leftharpoondown
   → \rightarrow ⇒ \Rightarrow ⇀ \rightharpoonup ⇁ \rightharpoondown
   ↑ \uparrow  ⇑ \Uparrow  \upharpoonleft  \upharpoonright
   ↓ \downarrow ⇓ \Downarrow  \downharpoonleft  \downharpoonright

may be used as heads, although they are rather small and also unsuitable for dotted lines (some of these symbols come from the AMS msxm10 and msym10 fonts). Instead

            < \lhvee  > \rhvee  ∨ \dhvee  ∧ \uhvee
            ≺ \lhcvee  ≻ \rhcvee  \dhcvee  \uhcvee
            ≪ \lhvvee  ≫ \rhvvee      ∨ ∨ \dhvvee      ∧ ∧ \uhvvee
             [figure: \lhla; \rhla; \dhla; \uhla]

produce better results. The following are also useful:

      \twoheadleftarrow ◁ \triangleleft  \blacktriangleleft
      \twoheadrightarrow ▷ \triangleright  \blacktriangleright
      ↑ ↑ \twoheaduparrow  △ \triangleup  \blacktriangle
      ↓ ↓ \twoheaddownarrow  \littletriangledown  \blacktriangledown

some of which have been “made up.”

The following are useful as tails:

        > \gt  < \lt  \blacktriangle  \blacktriangleleft
        ∧ \wedge ∨ \vee  \blacktriangledown  \blacktriangleright

together with the following made up symbols:

                   \ltbar  \rtbar  \utbar  \dtbar
               ⊂ \rthooka  _{⊂} \rthookb  ^{⊃} \lthooka  _{⊃} \lthookb
                ∪ \uthooka  ∪ \uthookb  ∩ \dthooka  ∩ \dthookb

which are designed for \rMapsto, \rIntoA, etc.

Subscripts and superscripts can be added to arrowheads:

\newcommand\rToStar{\HorizontalMap \empty - \empty - {\mathop{\rhvee}\limits^*}}
$$\begin{diagram}
A &\rToStar^f & B \\
\end{diagram}$$

produces A ^{f} >^{∗} B.

When designing new arrow styles you need to know the exact rules governing the way the bits are put together.

• All bits are individually set in \hboxes in maths mode.

• The shaft of the horizontal arrows is centred on the “math axis”, so that symbols (such as \scriptstyle arrowheads) which are not aligned on this axis must be \raised.

• The middle and tips of horizontal arrows are narrowed by \frac{1}{12}em on each side (this being the margin for most of the cmmi10 and cmsy10 characters) so that they join up with the filler.

• The middle and tips of the vertical arrows are horizontally centred, so to shift them left or right relative to the shaft it is necessary to kern by twice the required shift. Since there is no top or bottom margin on the standard characters, no shortening is done.

• The filler segments are shortened at each end by up to 0.15em (horizontal) or 0.35ex (vertical) so that when the repetitions are spaced out they will join up.

2.5 Extending vertical arrows

The cube offers a good example of how horizontal and vertical arrows stretch. Notice how the cells have been sub-divided further to give the “3D” effect., and that the positions of the labels on the maps betray the cells in which they were declared.

$$\begin{diagram}

        A'    &       &\rArr^{f'}&           &     B'     &      &        \\
              & \SE_a &           &           &\vLine^{h'}&\SE_b&        \\
    \dArr^{g'}&       &     A     &  \rArr^f  &   \HonV   &      &   B   \\
              &       &  \dArr^g  &           &   \dArr   &      &        \\
        C'    &\hLine&   \VonH   &\rArr^{k'}&     D'     &      &\dArr_h\\
              & \SE_c &           &           &            &\SE_d&        \\
              &       &     C     &           &  \rArr^k  &      &   D   \\

\end{diagram}$$

The broken lines (h′ and k′) are simply two arrows. The commands \HonV (“horizontal on vertical”) and \VonH (“vertical on horizontal”) allow arrows in one direction to pass through, whilst obstructing arrows in the other direction as if an object were present. They each have an optional argument: \HonV[=] and \VonH[\|] should be used to allow extra space for double lines. There is also a command \HmeetV which causes single horizontal and vertical lines to meet, forming a corner.

Here is the result:

A′  \overline{f′}  \overline{}B′

[figure: a; h′; b]

[figure: g′; A; \overline{f}; B]

[figure: g]

[figure: C′; \overline{k′}; D′; h]

[figure: c; d]

C  \overline{k}  \overline{}D

With a little practice, you will be able to read and compose the source of these diagrams as easily as the printed version, although one would not normally go to the trouble of aligning the &s in the source code!

2.6 Parallel arrows

One can draw two arrows between the same two vertices (possibly including extra things like the adjoint symbol in between) very simply:

$$\begin{diagram}

                 A         &\pile{\rTo^f\\ \bot\\ \lTo_g}&B\\
         \dTo^h\dashv\uTo_k&                              &  \\
                 C         &                              &  \\

\end{diagram}$$

A \overline{f} ; ⊥ ; < g \overline{>} B

∧

h∨⊣ k

C

• Horizontal arrows may be \piled on top of each other. Effectively, a one-column diagram is created, which may have either a horizontal arrow or an object in each row. This works both in diagrams and in text. The spacing (\baselineskip) between the rows is .5\PileSpacing, on the assumption that you will put something between parallel arrows; a blank line (\\ \\) will suffice, then the spacing is the same as that for vertical arrows.

• Vertical arrows may simply be put together in the same cell, with any text between them. The spacing is always \PileSpacing. (\pile must not be used.)

• The experimental \ParallelMap command (which appeared in the source of previous versions but never worked) has not been and will not be implemented.

• Diagonal lines are currently implemented as fixed (non-stretching) boxes and can therefore be juxtaposed, separated with explicit space and moved with \raise or \raisebox commands. However this will be incompatible with future versions.

2.7 Diagonal lines

As we have already said, TEX makes drawing diagonal lines very difficult:

• there is no diagonal rule primitive: juxtaposed characters have to be used,

• there is no square root function to enable one to compute the diagonal length of a character (using Pythagoras),

• there is no diagonal leader function for repetition,

• positioning of line segments involves so many horizontal and vertical shifts that dvi drivers inevitably “lose their place” with rounding errors, so that the segments don’t join up.

Consequently, the provision of diagonal arrows in this package is rather primitive, and only single unbroken LaTEX-style arrows (like \rArr) are provided at the slopes indicated by the diagram. Notice that all of the diagonal lines lie between objects two cells apart in one direction and two, three, four or six cells apart the other way. Longer lines may be obtained with \NE(4,4)^f or \sSE(4,6)_g, for instance, but the numbers must be consistent and

\DiagramCellHeight and \DiagramCellWidth must be equal.

Those arrows which extend through several rows are declared in the top cell in which they print, i.e. in the row and column adjacent to the upper terminating object (irrespective of the sense of the arrow).

For example, here is the diagram defining a pullback:

$$\begin{diagram}

             U&                &                  &       &       \\
              &\SE\ESE^x\SSE_y&                  &       &       \\
              &                &X\times_Z\SEpbk Y&\rTo_p&   X   \\
              &                &      \dTo^q      &       &\dTo_f\\
              &                &        Y        &\rTo^g&   Z   \\

\end{diagram}$$

which gives

U

[figure: x; y]

X ×_{Z} Y \overline{p} \overline{>} X

q∨  ∨f

Y  \overline{g} \overline{>} Z

The “right angle” symbol \SEpbk is just like a character which prints way outside its (zero-size) bounding box. There are also three others for the rare cases where the pullback is not upwards and leftwards! Notice that the stretching algorithm aligns the g with the p.

2.8 Posets (Hasse Diagrams)

Posets are trivial categories, but in practice they’re the most difficult diagrams to draw! Here is an example which illustrates many of the foregoing techniques. [Make it more complicated!]

$$\CellSize=1em\MapsAbut\begin{diagram}

   o&          &o&        &  o  &       &  o  &        &o&          &o\\
     &\WNW\WWNW&  &\NW\WNW&\uArr&\NW\NE&\uArr&\ENE\NE&  &\EENE\ENE&  \\
     &          &  &        &  o  &       &  o  &        &  &          &  \\

\end{diagram}$$

o  o  o  o  o  o [figure]
[figure]
o  o

3 Implementation and compatibility

The diagram package is currently available as a single 30kb^{13} printable TEX source file which is compatible with both LaTEX and plain TEX. It loads the LaTEX line10 font as \tenln (its LaTEX name) and also defines some (exotic) arrow commands in terms the AMS symbols, but if these are to be used then the file mssymb.tex must be loaded separately.

Compatibility with past and future versions (the numbers of which have been assigned post facto) is as follows:

Version 0: Original implementation of TEXercise 18.46; April 1986.

• \matrix{..} must be changed to \diagram..\enddiagram (or \commdiag{..}).

• \mapright, etc., must be changed to (or defined as) \rTo. Positional arguments are still recognised, so long as they are enclosed in braces.

• \cr should be changed to \\.

Version 1: Horizontal arrows made to stretch to edge of cell; 1987–9.

• \rTo{f}{g} works, but \rTo f g doesn’t: it must be changed to \rTo^f_g.

• \mkern-20mu\rTo{f}{g}\mkern-20mu idiom for manual stretching of horizontal arrows to meet objects must be removed.

• \VerticalMapHeight and \VerticalMapDepth commands should be removed.
• There are now five arguments to \HorizontalMap, \VerticalMap and \DiagonalMap.

• Nested \commdiag commands for parallel maps should be changed to \pile.

• Parallel maps contructed by putting them in the rows or columns before and after must be moved to the correct cell and put in a \pile.

Version 2: Horizontal arrows made to stretch to meet objects and “superscript” labels introduced; widely circulated versions with a banner dated September to December 1989.

• &\rTo\across3& should be changed to &&\rTo&&; \across doesn’t work at all with objects, and is only supported for arrows for backwards compatibility.

• The parameters \HorizontalMapLength, \VerticalMapHeight, \VerticalMapDepth,
  \VerticalMapExtraHeight, \VerticalMapExtraDepth and \DiagonalLineSegments

are obsolete and should be removed.

• The labels on southeast and northwest diagonal lines have been interchanged (^and _previously meant left and right respectively for diagonals; they now mean — more logically — above and below).

• Diagonal lines are constructed differently; user-defined diagonal arrows should be replaced with \NNW etc., and explicit movement of them removed. Where it is still necessary to define additional diagonal arrow commands, the coordinates, e.g. (2,4) must be given, and should be added to the definition.

• Bent lines, with \dlBent and \ruBentto, currently do not work. Instead \HmeetV must be placed at the corner.

Version 3: Vertical maps also made to stretch to meet objects; current.

Future: Diagonal lines will be made to stretch in so far as this is possible, so explicit movement of diagonals will become incompatible. It is intended that a single command, such as \nwTo, will serve for all slopes, the slope being given by coordinates; since the parts of the arrow command will then the slope-dependent, the way of defining them will change.

13Without comments; the development version is twice this size.

The general rule with this version is to remove the hacks which were needed to position verticals etc. before. You must also be careful to ensure that every arrow is terminated by an object or pseudo-object at each end, and that there is the correct number of &s. Because of the way terminating objects control the behavious of arrows, this version is much less tolerant than earlier ones.

Suggestions for improvements and further applications (e.g. proof nets and Petri nets) are welcome.

In Imperial College, the package is available on /home/leonardo and will be picked up automatically by the tex and latex commands.

I would like to thank Simon Ambler, Roger Crew, Valeria de Paiva, Eugenio Moggi,, Luke Ong, Vaughn Pratt and Jane Spurr, who have used pre-release versions, for their comments and suggestions and request those who use this package in their published papers to acknowledge me.

$$\begin{diagram}

&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &    \NNNW    &      &\NNNE&     &     & &      &      \\
&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &    \NNW    &      & \NNE &     &     & &      &      \\
&      & &     &     &    \nNW    &      & \nNE &     &     & &      &      \\
&\WWNW& &\WNW&\wNW&     \NW     &\uArr& \NE &\eNE&\ENE& &\EENE&      \\
&      & &     &     &    \lArr    &  *  &\rArr&     &     & &      &      \\
&&&&&\WWSW\WSW\wSW\SW\sSW\SSW\SSSW&\dArr&\SE\eSE\sSE\ESE\SSE\SSSE\EESE&&&&&\\
&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &            &      &      &     &     & &      &      \\
&      & &     &     &            &      &      &     &     & &      &      \\

\end{diagram}$$

produces (the arrows but not the labels of):

                          \NNNW  \NNNE

[figure]

                           \NNW  \NNE
                           [figure: \nNW; \uArr; \nNE]
    [figure: \WWNW; \WNW; \wNW; \NW; \NE; \eNE; \ENE; \EENE]

[figure]

                     [figure: \lArr; ∗; \rArr]

[figure]

    \WWSW  \WSW \wSW \SW  \SE \eSE \ESE  \EESE
                           \sSW  \dArr  \sSE
                           \SSW  \SSE
                          \SSSW  \SSSE