The amsthm package

American Mathematical Society Michael Downes

29 October 1996 Version 1.02

1 Introduction

The amsthm package is loosely derived from theorem.sty version 2.1c; it adds \newtheorem* for unnumbered environments and changes the extensibility support for loading extra theorem styles from external files: now it is done through the package option mechanism.

Here are some examples showing the kinds of theorem environment declarations that are possible with the amsthm package.

 \newtheorem{prop}{Proposition}
 \newtheorem{thm}{Theorem}[section]
 \newtheorem{lem}[thm]{Lemma}
 \newtheorem*{Zorn}{Zorn's Lemma}
 \theoremstyle{definition}
 \newtheorem{dfn}{Definition}
 \theoremstyle{remark}
 \newtheorem*{rmk}{Remark}

The first four statements all define environments using the default theorem style (‘plain’), since there is no prefatory \theoremstyle declaration. The first statement defines an automatically numbered prop environment whose headings will look like this: Proposition 1, Proposition 2, and so forth. The second statement defines an environment thm with numbers subordinate to section numbers, so the headings will look like this: Theorem 1.1, Theorem 1.2, Theorem 1.3, …, (in section 2:) Theorem 2.1, Theorem 2.2, and so forth. The third statement defines a lem environment whose numbers will interleave in sequence with the theorem numbers: Theorem 1.3, Lemma 1.4, Lemma 1.5, Theorem 1.6, and so forth. The fourth statement defines a special unnumbered lemma named ‘Zorn’s Lemma’. The remaining two \newtheorem statements have no special features except for the \theoremstyle declarations that cause the dfn and rmk environments to have some differences in appearance.

There are three basic styles provided: The ‘plain’ style produces bold headings and italic body text; the ‘definition’ style produces bold headings and normal body text; the ‘remark’ style produces italic headings and normal body text.

A \swapnumbers command allows theorem numbers to be swapped to the front of the theorem headings. Putting \swapnumbers in your document preamble will cause all following \newtheorem statements to produce number-first headings. (To provide maximum control, \swapnumbers is designed so that it can be used more than once; each time it is used, theorem numbers will be swapped to the opposite side for all following \newtheorem statements. But rarely will it need to be invoked more than once per document.)

There is a \newtheoremstyle command provided to make the creation of custom theoremstyles fairly easy.

Usage:

                   #1
 \newtheoremstyle{NAME}%
     #2          #3          #4
   {ABOVESPACE}{BELOWSPACE}{BODYFONT}%
     #5      #6        #7         #8
   {INDENT}{HEADFONT}{HEADPUNCT}{HEADSPACE}%
     #9
   {CUSTOM-HEAD-SPEC}

Leaving the ‘indent’ argument empty is equivalent to entering 0pt. The ‘headpunct’ and ‘headspace’ arguments are for the punctuation and horizontal space between the theorem head and the following text. There are two special values that may be used for ‘headspace’: a single space means that a normal interword space should be used; “\newline” means that there should be a line break after the head instead of horizontal space. The ‘custom-head-spec’ argument follows a special convention: it is interpreted as the replacement text for an internal three-argument function \thmhead, i.e., as if you were defining

 \renewcommand{\thmhead}[3]{...#1...#2...#3...}

but omitting the initial \renewcommand{\thmhead}[3]. The three arguments that will be supplied to \thmhead are the name, number, and optional note components. Within the replacement text you can (and normally will want to) use other special functions \thmname, \thmnumber, and \thmnote. These will print their argument if and only if the corresponding argument of \thmhead is nonempty. For example

 {\thmname{#1}\thmnumber{ #2}\thmnote{ (#3)}}

This would cause the theorem note #3 to be printed with a preceding space and enclosing parentheses, if it is present, and if it is absent, the space and parentheses will be omitted because they are inside the argument of \thmnote.

Finally, if you have an extra bit of arbitrary code that you want to slip in somewhere, the best place to do it is in the ‘body font’ argument.

The \newtheoremstyle command is designed to provide, through a relatively simple interface, control over the style aspects that are most commonly changed. Clearly it cannot serve for all possible theorem styles. Therefore there is a second interface provided to allow arbitrary theorem styles by reading suitable definitions from a separate file whose name ends with .thm. If the desired style is far from any of the basic styles provided by the amsthm package, writing the definitions may require some expertise in L^{A}TEX’s macro language.

Suppose that you wanted to make a theorem style ‘exercise’ for exercises. Create a file called exercise.thm and in it define a command \th@exercise

following the form of the commands \th@plain, \th@definition, \th@remark

given below. Then to use the new style, write

 \usepackage[exercise]{amsthm}
 ...
 \theoremstyle{exercise}

Similarly, it’s possible to place a group of related \newtheoremstyle statements in a .thm file, let’s say stygroup.thm, so that they could be loaded on demand in various documents by

 \usepackage[stygroup]{amsthm}

This strategy fails if you want to load a .thm file in a document preamble and the amsthm package has already been loaded in the documentclass (e.g., amsart). Then you need to use a statement such as

 \PassOptionsToPackage{stygroup}{amsthm}

before the \documentclass command.

2 Implementation

Standard declaration of package name and date.

  \NeedsTeXFormat{LaTeX2e}% LaTeX 2.09 can't be used (nor non-LaTeX)
  [1994/12/01]% LaTeX date must December 1994 or later
  \ProvidesPackage{amsthm}[1996/10/24 v1.2d]

Load some utility functions from amsgen if it is not already loaded. Can’t use \RequirePackage because of the later \ProcessOptions command, and can’t put this after the \ProcessOptions command because we might need some bits for processing a .thm file.

  \@ifpackageloaded{amsgen}{}{\input{amsgen.sty}}

The \theoremstyle command is very simple except for the need to warn about an unknown theoremstyle.

  \newcommand{\theoremstyle}[1]{%

    \@ifundefined{th@#1}{%
      \PackageWarning{amsthm}{Unknown theoremstyle `#1'}%
      \thm@style{plain}%
    }{%
      \thm@style{#1}%
    }%
  }
  \newtoks\thm@style
  \thm@style{plain}

This code for handling theorem body and header font is a simplification of the code in Mittelbach’s theorem package. For consistency we make the header punctuation a token register as well. And we add a separate font specification for the optional note (since in AMS publications the note usually takes a different font). The \normalfont that in Mittelbach’s code resided here is transferred to

\@thm.

Note: \thm@bodyfont is an artifact of borrowing from theorem.dtx and requires more consideration of possible repercussions before it is adopted or removed. For now, comment it out, and advise anyone who asks that the recommended way to make such changes is to use the \newtheoremstyle facility. [bnb, 1996/09/24]

Note: Similarly for \thm@notefont; current methods inadequate, more work needed. [mjd, 1995/08/07] What’s really needed is a full-fledged systematic approach for specifying the desired order and formatting of the three identified parts of a theorem head (name, number, note). In the absence of such a solution, the use of \thm@notefont (but not \theoremnumberfont) seems to be more harm than good: if you need to change it, as likely as not you’ll need to change something else that’s not as accessible, so you might as well go to

\newtheoremstyle or direct surgery on \thmhead@plain or whatever.
  \newtoks\thm@bodyfont
  \thm@bodyfont{\itshape}
  \newtoks\thm@headfont
  \thm@headfont{\bfseries}
  \newtoks\thm@notefont
  \thm@notefont{}
  \newtoks\thm@headpunct
  \thm@headpunct{.}

Vertical spacing: initialize to current value of \topsep. If a document class loads the amsthm package it should take care to set these variables explicitly, if current \topsep is not the desired value.

  \newskip\thm@preskip \thm@preskip\topsep
  \newskip\thm@postskip \thm@postskip\topsep

Modify \newtheorem to add * option. If a * is found, pass it on to \@xnthm as the first argument. (This information enables us to handle two different possibilities in a single function \@xnthm instead of needing two separate functions.)

  \renewcommand{\newtheorem}{\@ifstar{\@xnthm *}{\@xnthm \relax}}

2. IMPLEMENTATION 5

Check to see if an optional arg is present after the first mandatory arg (which is #2 at the moment since the * or non-* is #1).

\def\@xnthm#1#2{%
\let\@tempa\relax
\@xp\@ifdefinable\csname #2\endcsname{%
  \global\@xp\let\csname end#2\endcsname\@endtheorem
  \ifx *#1% unnumbered, need to get one more mandatory arg
    \edef\@tempa##1{%
      \gdef\@xp\@nx\csname#2\endcsname{%
        \@nx\@thm{\@xp\@nx\csname th@\the\thm@style\endcsname}%
          {}{##1}}}%
  \else % numbered theorem, need to check for optional arg
    \def\@tempa{\@oparg{\@ynthm{#2}}[]}%
  \fi
}%
\@tempa
}

Environment numbered together with a previously defined environment. Arg1: env name, e.g. ‘thm’ Arg2: optional sibling counter Arg3: heading text e.g. ‘Theorem’

\def\@ynthm#1[#2]#3{%

If optional arg #2 is empty, call \@xthm to look for a possible optional arg in terminal position. Note that the two optional args are mutually exclusive. As #2 is a counter name and must be processed by \csname anyway, we can use a simpler test instead of \@ifempty.

\ifx\relax#2\relax
  \def\@tempa{\@oparg{\@xthm{#1}{#3}}[]}%
\else
  \@ifundefined{c@#2}{%
    \def\@tempa{\@nocounterr{#2}}%
  }{%
    \@xp\xdef\csname the#1\endcsname{\@xp\@nx\csname the#2\endcsname}%
    \toks@{#3}%
    \@xp\xdef\csname#1\endcsname{%
      \@nx\@thm{%
        \let\@nx\thm@swap
          \if S\thm@swap\@nx\@firstoftwo\else\@nx\@gobble\fi
        \@xp\@nx\csname th@\the\thm@style\endcsname}%
          {#2}{\the\toks@}}%
    \let\@tempa\relax
  }%
\fi
\@tempa
}

Environment numbered relative to the counter given as #3. This function should really be named \@znthm but we’re trying to save a bit of hash table and string pool by reusing one of the command names rendered obsolete by the amsthm option.

Arg1: env name e.g. ‘thm’; Arg2: heading text e.g. ‘Theorem’; Arg3: parent counter e.g. section.

  \def\@xthm#1#2[#3]{%

Set up the counter c@#1 and optionally add it to the reset list of counter #3. As #3 is a counter name and must be processed by \csname anyway, we can use a simpler test instead of \@ifempty.

    \ifx\relax#3\relax
      \newcounter{#1}%
    \else
      \newcounter{#1}[#3]%

Define \thexxx to be \theyyy.\arabic{xxx} (assuming default values of punctuation and numbering style). The use of \xdef here is inherited from the old L^{A}TEX code, I’m not sure it’s a good idea in general, but there should not be any problems unless someone changes the value of \@thmcounter or \@thmcounter.

      \@xp\xdef\csname the#1\endcsname{\@xp\@nx\csname the#3\endcsname
        \@thmcountersep\@thmcounter{#1}}%
    \fi
    \toks@{#2}%
    \@xp\xdef\csname#1\endcsname{%
      \@nx\@thm{%
        \let\@nx\thm@swap
          \if S\thm@swap\@nx\@firstoftwo\else\@nx\@gobble\fi
        \@xp\@nx\csname th@\the\thm@style\endcsname}%
        {#1}{\the\toks@}}%
  }

If arg #2 is empty, this is an unnumbered environment; otherwise #2 is the name of a counter. #3 is descriptive name such as “Theorem” or “Lemma”. Arg #1 is the style function, for example \th@plain.

  \def\@thm#1#2#3{\normalfont
    \trivlist

Explicitly set plain style here, then override parts as necessary in the function provided as #1. As far as I can tell the standard article/book documentclasses don’t handle nonstandard values of \labelsep well: if you start any kind of list or trivlist and modify the value of labelsep, then the same value will be used for embedded enumerate’s or itemize’s because the normal value is not restored by \@listi (nor by ii,iii,...). So let’s save current labelsep by hand in order to restore it later.

    \edef\@restorelabelsep{\labelsep\the\labelsep}%
    \labelsep.5em\relax \let\thmheadnl\relax
    \let\thm@indent\noindent % no indent
    \let\thm@swap\@gobble
    \thm@headfont{\bfseries}% heading font bold
    \thm@headpunct{.}% add period after heading
    \thm@preskip\topsep

    \thm@postskip\thm@preskip
    #1% style overrides
    \@topsep \thm@preskip               % used by first \item
    \@topsepadd \thm@postskip           % used by \@endparenv
    \def\@tempa{#2}\ifx\@empty\@tempa
      \def\@tempa{\@oparg{\@begintheorem{#3}{}}[]}%
    \else
      \refstepcounter{#2}%
      \def\@tempa{\@oparg{\@begintheorem{#3}{\csname the#2\endcsname}}[]}%
    \fi
    \@tempa
  }

This variation of the \@thm command is no longer needed. The variation \@xthm was commandeered for \newtheorem use.

  \let\@ythm\relax
   Init \thmname etc.
  \let\thmname\@iden \let\thmnote\@iden \let\thmnumber\@iden

\@upn If a suitable italic font with upright numbers and punctuation is available, this

function should be redefined to be a no-op.

  \providecommand\@upn{\textup}

Definitions for theorem heads.

  \def\thmhead@plain#1#2#3{%

To allow for the case where the thmname part is empty and the heading consists only of a number (don’t laugh, we have examples from real mathematical manuscripts), we don’t add the space at the beginning of thmnumber unless #1 is nonempty.

    \thmname{#1}\thmnumber{\@ifnotempty{#1}{ }#2}%

In thmnote we always add a leading space, i.e., assuming that at least one of the preceding parts will always be present.

    \thmnote{ {\the\thm@notefont(#3)}}}
  \let\thmhead\thmhead@plain

Swappedhead is for the case where the number precedes the word ”Theorem”.

  \def\swappedhead#1#2#3{%
    \thmnumber{#2}\thmname{\@ifnotempty{#2}{. }#1}%
    \thmnote{ {\the\thm@notefont(#3)}}}

In \@begintheorem \thmheadnl is called after the theorem head: maybe a newline, otherwise a no-op.

  \let\thmheadnl\relax

If argument #2 is empty, then this is an unnumbered environment. Otherwise #2 is a numbering command such as \thexyz.

  \def\@begintheorem#1#2[#3]{%
    \item[\normalfont % reset in case body font is abnormal

The standard weird compensation for labelsep space inside a \trivlist\item:

    \hskip\labelsep
    \the\thm@headfont
    \thm@indent

Changes to \thmnumber and \thmnote are local to this group.

    \@ifempty{#1}{\let\thmname\@gobble}{\let\thmname\@iden}%
    \@ifempty{#2}{\let\thmnumber\@gobble}{\let\thmnumber\@iden}%
    \@ifempty{#3}{\let\thmnote\@gobble}{\let\thmnote\@iden}%
The \thm@swap function selects either \swappedhead or \thmhead.
    \thm@swap\swappedhead\thmhead{#1}{#2}{#3}%

I can’t think of any example where the after-head punctuation should be omitted so it seems correct not to use \@addpunct here.

    \the\thm@headpunct]%
    \@restorelabelsep
    \thmheadnl % possibly a newline.
    \ignorespaces}

\nonslanted The \nonslanted command changes the current font to \upshape if it is \itshape or \slshape. This is used for document structure numbers that should be consistently upright in all contexts.

  \def\nonslanted{\relax

Can’t do a direct \ifx between \f@shape and \itdefault because the latter is \long (grumble grumble).

    \@xp\let\@xp\@tempa\csname\f@shape shape\endcsname
    \ifx\@tempa\itshape\upshape
    \else\ifx\@tempa\slshape\upshape\fi\fi}
\swapnumbers The \swapnumbers command sets a switch \thm@swap that is used by \newtheorem.

To conserve hash table we load \thm@swap with two uses; the first one is needed only in \newtheorem declarations and the second one is needed only in typesetting theorem environments.

  \def\swapnumbers{\edef\thm@swap{\if S\thm@swap N\else S\fi}}
  \def\thm@swap{N}%

\@opargbegintheorem not needed, \@oparg utility serves instead.

  \let\@opargbegintheorem\relax

Except for the body font, default values are built into \@thm.

  \def\th@plain{%
  %%  \let\thm@indent\noindent % no indent
  %%  \thm@headfont{\bfseries}% heading font is bold
  %%  \thm@notefont{}% same as heading font
  %%  \thm@headpunct{.}% add period after heading
  %%  \let\thm@swap\@gobble
  %%  \thm@preskip\topsep
  %%  \thm@postskip\theorempreskipamount
    \itshape % body font
  }

Theorem style ‘definition’ is the same as ‘plain’ except for the body font.

  \def\th@definition{%
    \normalfont % body font
  }

Theorem style ‘remark’ differs from ‘plain’ in head font and body font. Also smaller spacing above and below.

  \def\th@remark{%
    \thm@headfont{\itshape}%
    \normalfont % body font
    \thm@preskip\topsep
    \divide\thm@preskip\tw@
    \thm@postskip\thm@preskip
  }

The standard definition of \@endtheorem is just \endtrivlist, but that doesn’t automatically start a new paragraph, so we add \@endpefalse in order to ensure a new paragraph.

  \def\@endtheorem{\endtrivlist\@endpefalse }

\newtheoremstyle An easy way to make a not too complicated variant theorem style. Usage:

                   #1
 \newtheoremstyle{NAME}%
     #2          #3          #4
   {ABOVESPACE}{BELOWSPACE}{BODYFONT}%
     #5      #6        #7         #8
   {INDENT}{HEADFONT}{HEADPUNCT}{HEADSPACE}%
     #9
   {CUSTOM-HEAD-SPEC}

  \newcommand{\newtheoremstyle}[9]{%

Empty or 0pt for #5 is translated to \noindent.

    \@ifempty{#5}{\dimen@\z@skip}{\dimen@#5\relax}%
    \ifdim\dimen@=\z@

#4 is body font. Extra code could be included there if necessary.

      \toks@{#4\let\thm@indent\noindent}%
    \else
      \toks@{#4\def\thm@indent{\noindent\hbox to#5{}}}%
    \fi

Arg #8 is a glue spec for the space after the head. As a proper glue spec for ‘normal interword space’ is rather hard to write, we recognize an argument of { } as a special case and translate internally to the necessary fontdimen equivalent. Furthermore, if #8 consists entirely of \newline, then we will perform a line break after the theorem head instead of adding horizontal space. At the moment [1995/01/23] this is not perfectly well implemented because of complications with the way L^{A}TEX’s \item adds a heading to the vertical list; for best results 10 THE AMSTHM PACKAGE

there should not be anything (not even a blank line) after the \begin{xxx} command.

\def\@tempa{#8}\ifx\space\@tempa

Notice that we disregard stretch and shrink for labelsep = interwordspace.

  \toks@\@xp{\the\toks@ \labelsep\fontdimen\tw@\font\relax}%
\else
  \def\@tempb{\newline}%
  \ifx\@tempb\@tempa
    \toks@\@xp{\the\toks@ \labelsep\z@skip
      \def\thmheadnl{%

In the following line, the ‘noskipsec’ switch prevents a following list item from running in on the same line as the theorem head; the ‘nobreak’ switch helps get the vertical spacing right.

        \@noskipsectrue \global\@nobreaktrue

If the first thing in the theorem is a list, this definition of \everypar will be overridden with something suitable.

        \everypar{\global\@minipagefalse \global\@newlistfalse
          \global\@inlabelfalse \global\@nobreakfalse

Remove the parindent box and put down the theorem head in its place.

          {\setbox\z@\lastbox}\box\@labels\par

For the ‘newline’ style of theorem head, there’s no easy way to adjust the vertical space between the head and the following text. A user syntax decision, basically. Don’t want to deal with it at the moment. [mjd,1995/07/27]

          \nobreak\vskip-\parskip
          \everypar{}\noindent}}%
    }%
  \else
    \toks@\@xp{\the\toks@ \labelsep#8\relax}%
  \fi
\fi
\begingroup \th@plain % to set \thm@preskip and postskip
\@defaultunits\@tempskipa#2\thm@preskip\relax\@nnil
\@defaultunits\@tempskipb#3\thm@postskip\relax\@nnil
\xdef\@gtempa{\thm@preskip\the\@tempskipa
  \thm@postskip\the\@tempskipb\relax}%
\endgroup
\@temptokena\@xp{\@gtempa
  \thm@headfont{#6}\thm@headpunct{#7}%
}%
\@ifempty{#9}{%
  \let\thmhead\thmhead@plain
}{%
  \@namedef{thmhead@#1}##1##2##3{#9}%
  \@temptokena\@xp{\the\@temptokena
    \@xp\let\@xp\thmhead\csname thmhead@#1\endcsname}%
}%

    \@xp\xdef\csname th@#1\endcsname{\the\toks@ \the\@temptokena}%
  }

\qed Define \qed for end of proof. This command might occur in math mode, in a displayed equation, but it should never occur in inner math mode in ordinary paragraph text.

  \DeclareRobustCommand{\qed}{%
    \ifmmode % if math mode, assume display: omit penalty etc.
    \else \leavevmode\unskip\penalty9999 \hbox{}\nobreak\hfill
    \fi

The hbox is to prevent a line break within the \qedsymbol if it is defined to be something composite— e.g., things like (Corollary 1.2) \openbox as are occasionally done.

    \quad\hbox{\qedsymbol}}

The reason that we do not simply use the \square symbol from msam for the open-box qed symbol is that we want to avoid requiring users to have the AMSFonts font package. And the lasy \Box is too large.

  \newcommand{\openbox}{\leavevmode

I think I got these numbers from measuring msam’s \square but I forgot to make notes at the time. [mjd,1995/01/25]

    \hbox to.77778em{%
    \hfil\vrule
    \vbox to.675em{\hrule width.6em\vfil\hrule}%
    \vrule\hfil}}
  \newcommand{\qedsymbol}{\openbox}

The proof environment is never numbered, and has a \qed at the end, which makes it inconvenient to use \newtheorem for defining it. Also authors frequently need to substitute an alternative heading text (e.g. ‘Proof of Lemma 4.3’) instead of the default ‘Proof’. For all these reasons we define the proof environment here instead of leaving it for authors to define.

  \newenvironment{proof}[1][\proofname]{\par
    \normalfont
    \topsep6\p@\@plus6\p@ \trivlist
    \item[\hskip\labelsep\itshape
      #1\@addpunct{.}]\ignorespaces
  }{%
    \qed\endtrivlist
  }

Default for \proofname:

  \newcommand{\proofname}{Proof}

Any option given in the \usepackage statement will be treated as the name of a file containing additional theorem style definitions.

  \DeclareOption*{\input{\CurrentOption .thm}}
  \ProcessOptions

For reference:

 From: tycchow@math.mit.edu (Timothy Y. Chow)
 Subject: Suppressing theorem numbering in LaTeX
 Message-ID: <1994Aug11.234754.22523@galois.mit.edu>
 Date: Thu, 11 Aug 94 23:47:54 GMT
 To: tex-news@SHSU.EDU
 A friend of mine wants numbering of theorems, conjectures, and so on
 suppressed if there is only one of them in his article.  In other words
 he wants "Conjecture 1" to appear as simply "Conjecture" if there is no
 Conjecture 2.  What is the best way to go about doing this?
 ...

Maybe something clever can be done to make the desired behavior happen automatically. Note that this would seem to be a general numbering problem rather than a theorem-specific one, because similar behavior would be desirable for appendixes: according to standard publishing practice, if there’s only one it is titled just ‘Appendix’, and if there are more than one they are titled ‘Appendix A’, ‘Appendix B’, and so on.

The usual \endinput to ensure that random garbage at the end of the file doesn’t get copied by docstrip.

  \endinput
   Changed some names from e.g., \theoremheadfont to \thm@headfont to

avoid confusion with variables of the same name (but used differently) from the ‘thm’ package.