Das hohle Quadrat am Ende eines Beweises ist kein Zeichen aus irgendeiner Schrift. amsthm zeichnet es an Ort und Stelle aus zwei senkrechten und zwei waagerechten Linien (\openbox in amsthm.sty; gemessen 7.77786pt breit und 6.75003pt hoch, also 0.77778em × 0.675em in einem 10pt-Dokument). Satzumgebungen funktionieren nach demselben Gedanken. LaTeX liefert keinen fertigen „Satz“, sondern \newtheorem, einen Deklarationsmechanismus; was als Satz gilt und wie nummeriert wird, entscheidet der Schreibende. Diese Seite verfolgt, was \newtheorem tatsächlich erzeugt, warum sich seine beiden optionalen Argumente nicht kombinieren lassen, was \theoremstyle wirklich ändert, und das \qedhere-Problem, bei dem das Beweisendezeichen in der falschen Zeile landet – jeweils mit den Ergebnissen echter Läufe.
Was \newtheorem erzeugt: eine Umgebung und einen Zähler
\newtheorem{theorem}{Theorem} erzeugt eine Umgebung und einen Zähler, der sie nummeriert. Im Protokoll erscheint eine Zeile wie \c@theorem=\count196 – der Zähler wird also tatsächlich reserviert. Das erste Argument ist der Umgebungsname, den man in \begin{…} schreibt, das zweite das Wort, das fett in der Überschrift steht. Entscheidend ist, dass beides Verschiedenes ist: Der Umgebungsname kann schlicht theorem bleiben, während nur das gedruckte Wort zu Satz oder Théorème wird.
\usepackage{amsthm}
\newtheorem{theorem}{Theorem} % declares the environment AND allocates a counterNach dieser Deklaration erhält jede Verwendung der Umgebung theorem eine fette Überschrift mit laufender Nummer – Theorem 1, Theorem 2 – und der Inhalt wird im Standardstil kursiv gesetzt. Die Nummer steckt in einem LaTeX-Zähler; ein nachträglich eingeschobener Satz verschiebt alle folgenden Nummern automatisch. Genau darum geht es bei der Suche nach Satznummerierung: Solange keine Nummer von Hand getippt wird, kann die Zählung nicht auseinanderlaufen.
\begin{theorem}
There are infinitely many primes.
\end{theorem}
\begin{theorem}[Pythagoras]
In a right triangle, $a^2 + b^2 = c^2$.
\end{theorem}Wie im zweiten Beispiel wird ein Name, den man direkt nach \begin{theorem} in eckigen Klammern übergibt, in Klammern hinter die Nummer gesetzt: „Theorem 2 (Pythagoras).“ Das ist unabhängig davon, ob die Umgebung nummeriert ist, und funktioniert ebenso in den unnummerierten Umgebungen, die weiter unten mit \newtheorem* entstehen. \newtheorem selbst gehört übrigens zum Standard-LaTeX2e. Schon das reine \newtheorem erzeugt nummerierte Umgebungen; \theoremstyle, \newtheorem*, die proof-Umgebung und \qedhere – alles Folgende – sind dagegen Erweiterungen von amsthm und stehen erst nach \usepackage{amsthm} bereit.
Die zwei Klammern: Teilen und Unterordnen lassen sich nicht kombinieren
\newtheorem nimmt genau eine Klammer entgegen, und ihre Position entscheidet über die Bedeutung. Direkt nach dem Umgebungsnamen bedeutet sie „einen vorhandenen Zähler mitbenutzen“, nach dem zweiten Argument „den Zähler diesem Elternzähler unterordnen und mit ihm zurücksetzen“. Getrennte Zählungen für Sätze und Lemmata streuen dieselben Nummern – „Theorem 1, Lemma 1, Theorem 2, Lemma 2…“ –, deshalb wählen die meisten mathematischen Texte die erste Variante und führen eine einzige Folge: „Theorem 1, Lemma 2, Theorem 3…“.
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma} % bracket BEFORE: share theorem's counter
\newtheorem{definition}{Definition}[section] % bracket AFTER: reset per section, "2.1"In die nachgestellte Klammer kann statt section auch eine vorhandene Satzumgebung. Mit \newtheorem{corollary}{Corollary}[theorem] wird die Korollarnummer bei jedem neuen Satz zurückgesetzt, sodass „Corollary 3.1“ als „das erste Korollar zu Theorem 3“ zu lesen ist.
| Deklaration | Wirkung |
|---|---|
\newtheorem{theorem}{Theorem} | Nummeriert 1, 2, 3, … mit einem eigenen Zähler |
\newtheorem{lemma}[theorem]{Lemma} | Teilt den Zähler von theorem; Lemmata und Sätze bilden eine Folge |
\newtheorem{theorem}{Theorem}[section] | Beginnt bei jedem \section neu und erscheint mit Abschnittsnummer als „2.1“ |
\newtheorem{corollary}{Corollary}[theorem] | Setzt bei jedem theorem zurück, erbt dessen Nummer und erscheint als „3.1“ |
\newtheorem*{remark}{Remark} | Legt keinen Zähler an und druckt nur das Überschriftenwort, unnummeriert (braucht amsthm) |
Was passiert also, wenn man beides gleichzeitig schreibt? \newtheorem{lemma}[theorem]{Lemma}[section] erzeugt unter TeX Live 2024 durchaus einen Fehler – der aber kein Wort über \newtheorem verliert. Da \newtheorem keine zweite Klammer liest, bleibt [section] als gewöhnlicher Text in der Präambel stehen, und LaTeX schließt daraus, der Dokumenttext habe begonnen. Herauskommt diese Meldung.
! LaTeX Error: Missing \begin{document}.
l.4 \newtheorem{lemma}[theorem]{Lemma}[
section]Teilen und Unterordnen schließen sich also gegenseitig aus. Will man beides – „Lemmata teilen die Satznummerierung, und diese beginnt in jedem Abschnitt neu“ –, gehört das [section] nur an den Elternzähler. Deklariere \newtheorem{theorem}{Theorem}[section]; ein über \newtheorem{lemma}[theorem]{Lemma} mitzählendes Lemma übernimmt die Abschnittsnummerierung dann automatisch. Da es nur einen Zähler gibt, erfüllt das beide Wünsche widerspruchsfrei.
Wenn Command \theorem already defined. erscheint
Dieser Fehler bedeutet, dass derselbe Umgebungsname zweimal deklariert wurde. \newtheorem legt eine neue Umgebung an und weigert sich daher, einen bereits vorhandenen Namen zu überschreiben. So sieht es aus, wenn \newtheorem{theorem}{Theorem} zweimal in derselben Präambel steht.
! LaTeX Error: Command \theorem already defined.
Or name \end... illegal, see p.192 of the manual.In der Praxis liegt es selten daran, dass die Zeile zweimal getippt wurde. Meist hat die Dokumentklasse oder ein geladenes Paket theorem bereits deklariert. Konferenzvorlagen, amsart oder elsarticle richten Satzumgebungen mitunter vorab ein. Es gibt drei Auswege: die eigene Zeile löschen, sie in etwa mytheorem umbenennen, oder die vorhandene Deklaration behalten und nur \theoremstyle anpassen. Geht es allein um ein anderes Überschriftenwort für eine bestehende Umgebung, ist der klasseneigene Weg schneller als \newtheorem.
Was \theoremstyle ändert: Schrift für Kopf und Text
\theoremstyle aus amsthm wechselt die Schriftkombination für Überschrift (head) und Text (body). Eingebaut sind drei Stile: plain, definition und remark. Entscheidend ist, dass \theoremstyle{…} nur auf die danach geschriebenen \newtheorem-Zeilen wirkt. Ein Stil unterhalb einer Deklaration gilt nicht rückwirkend; gruppiere die Deklarationen in der Präambel daher nach Stil. Ohne Angabe gilt plain.
plain: fette Überschrift, kursiver Text. Für betont formulierte Aussagen: Sätze, Lemmata, Propositionen, Korollare. Der Standard, wenn nichts gesetzt wird.definition: fette Überschrift, aufrechter (roman) Text. Für Inhalte, die wie gewöhnliche Prosa gelesen werden sollen: Definitionen, Beispiele, Aufgaben, Bedingungen. Aufrecht liest sich besser, wenn Formeln vorkommen oder der Text länger wird.remark: kursive Überschrift, aufrechter Text. Für Nebenbemerkungen: Bemerkungen, Notizen, Claims. Da auch die Überschrift leichter wird, stört sie den Fluss des umgebenden Textes nicht.
\usepackage{amsmath, amsthm}
\theoremstyle{plain} % italic body
\newtheorem{theorem}{Theorem}[section]
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\theoremstyle{definition} % upright body
\newtheorem{definition}[theorem]{Definition}
\newtheorem{example}[theorem]{Example}
\theoremstyle{remark} % italic head
\newtheorem*{remark}{Remark}In dieser Einrichtung teilen sich theorem, lemma, corollary, definition und example eine einzige abschnittsweise Folge (Theorem 2.1, Definition 2.2, Lemma 2.3…); die ersten drei mit kursivem, die letzten beiden mit aufrechtem Text. Nur remark trägt keine Nummer, seine Überschrift „Remark“ ist kursiv. Dass sich Nummern teilen und Schriften trennen lassen, liegt daran, dass Zähler und Stil zwei voneinander unabhängige Achsen sind.
Die proof-Umgebung und das QED-Zeichen in der falschen Zeile
Die proof-Umgebung von amsthm beginnt mit einem kursiven „Proof.“ und schließt automatisch mit \qedsymbol, standardmäßig □. proof versucht das Zeichen jedoch ans Ende der letzten Absatzzeile zu setzen; endet ein Beweis mit einer abgesetzten Gleichung, fehlt diese Zeile, und das □ rutscht allein in eine eigene Zeile. Das ist kein Eindruck, sondern messbar. Legt man denselben Beweis in eine \vbox und misst die Höhe, ergibt sich:
% \vbox{\hsize=8cm \begin{proof}Compute:\[a^2+b^2=c^2.\]\end{proof}}
without \qedhere h = 66.94444pt
with \qedhere h = 47.77777pt % 19.16667pt shorter: one whole line savedDie Differenz beträgt 19.16667pt – genau eine Zeile. \qedhere ist die Anweisung „setze das Zeichen hier“: am Ende einer abgesetzten Gleichung geschrieben, schmiegt es das □ an den rechten Rand dieser Zeile, und die zusätzliche Zeile verschwindet. \qedhere funktioniert in equation, align und gather* sowie im letzten Punkt eines enumerate (alles unter TeX Live 2024 fehlerfrei nachgestellt). Wo das Zeichen nicht sauber unterzubringen ist, meldet amsthm: Package amsthm Warning: The \qedhere command may not work correctly here – ein Blick ins Protokoll genügt.
\begin{proof}
Rearranging both sides gives
\[
a^2 + b^2 = c^2. \qedhere
\]
\end{proof}Sowohl das Überschriftenwort als auch das Endzeichen lassen sich ersetzen. Ein einzelner Beweis nimmt eine Klammer entgegen, etwa \begin{proof}[Proof of Theorem 1]; die dokumentweite Vorgabe steckt in \proofname, das man neu definiert (\renewcommand{\proofname}{Demonstration} erzeugte nachweislich die Überschrift „Demonstration.“). Das Endzeichen ist eine Neudefinition von \qedsymbol. Wie eingangs erwähnt, ist die Vorgabe \openbox, das aus Linien gezeichnete hohle Quadrat – mit $\blacksquare$ wird daraus ein gefülltes Quadrat, und leer definiert verschwindet die Markierung ganz. Zu beachten: \blacksquare stammt aus amssymb (Zeile 48 von amssymb.sty); mit amsthm allein erhält man ! Undefined control sequence. – \usepackage{amssymb} nicht vergessen.
\usepackage{amssymb} % \blacksquare lives here, not in amsthm
\renewcommand{\proofname}{Demonstration} % heading word for every proof
\renewcommand{\qedsymbol}{$\blacksquare$} % filled square instead of the hollow one
% \renewcommand{\qedsymbol}{} % no end-of-proof marker at allthmtools: Klammerpositionen durch key=value ersetzen
Spätestens bei einem Dutzend Deklarationen wird die Konvention von \newtheorem – Bedeutung durch Klammerposition – schwer lesbar. thmtools (in TeX Live 2024: 2023/05/04 v0.76) ist eine höhere Schnittstelle über amsthm (oder ntheorem), mit der sich dieselben Einstellungen über \declaretheorem als key=value schreiben lassen. Es besitzt keine eigene Nummerierungslogik, sondern ruft darunter schlicht \newtheorem von amsthm auf; man lädt es daher zusammen mit amsthm.
\usepackage{amsmath, amsthm, thmtools, thm-restate}
\declaretheorem[numberwithin=section]{theorem} % same as [section] after arg 2
\declaretheorem[sibling=theorem]{lemma} % same as [theorem] after arg 1
\declaretheorem[style=definition, sibling=theorem]{definition}
\declaretheorem[numbered=no, name=Remark]{remark}Die Schlüssel bilden das direkt ab. Unterordnung unter einen Abschnitt ist numberwithin= (Synonyme parent=, within=), das Teilen eines Zählers sibling= (Synonyme numberlike=, sharecounter=), unnummeriert numbered=no, das Überschriftenwort name= (Synonyme title=, heading=) und die Gestalt style=. Setzt man die obige Präambel wirklich, folgt auf Theorem 1.1 direkt Lemma 1.2 – die Ausgabe bestätigt, dass sibling= tatsächlich eine gemeinsame Folge bildet.
Der eigentliche Grund für thmtools sind zwei Funktionen, die mit amsthm allein umständlich wären. Die erste ist das Wiederholen (restatable). Lädt man das mitgelieferte thm-restate und schreibt einen Satz in eine restatable-Umgebung, wird sein Inhalt als Makro gespeichert und lässt sich später mit derselben Nummer erneut setzen. So stellt man eine Aussage nummeriert in den Haupttext und verschiebt nur den Beweis in den Anhang. Im echten Lauf erschien das Theorem 1.1 des Haupttextes im Anhang wieder als Theorem 1.1.
\begin{restatable}[Euclid]{theorem}{firsteuclid}
\label{thm:euclid}
There are infinitely many primes.
\end{restatable}
% later, e.g. in an appendix — same number, references still point at the original
\firsteuclid*restatable nimmt einen optionalen Namen, dann die zu verwendende Satzumgebung und schließlich den Makronamen, der den Inhalt behält. Expandiert man später \firsteuclid, wird der Satz erneut gesetzt, die Nummer bleibt an die erste Stelle geheftet. Das gesternte \firsteuclid* wiederholt ihn, während \label/\ref auf die ursprüngliche Deklaration statt auf die Kopie zeigen. Die zweite Funktion ist das Satzverzeichnis: \listoftheorems erzeugt eine inhaltsverzeichnisartige Liste, und ignoreall zusammen mit show={…} grenzt sie auf gewählte Umgebungen ein. Außerdem gibt es onlynamed, das nur über \begin{…}[name] benannte Sätze aufnimmt; mit geladenem hyperref wird jeder Eintrag zum Link auf den Satz.
\listoftheorems % everything
\listoftheorems[ignoreall, show={theorem, lemma}] % only these two
\listoftheorems[ignoreall, show={theorem}, onlynamed] % only the ones you namedFür ein eigenes Erscheinungsbild definiert man mit \declaretheoremstyle einen Stil und ruft ihn über \declaretheorem[style=…]{…} auf. Schlüssel gibt es für die Überschriftenschrift headfont, die Textschrift bodyfont, Abstände darüber und darunter (spaceabove, spacebelow), die Klammern um den Namen (notebraces), den Abstand nach der Überschrift (postheadspace), das Endzeichen (qed) und mehr. Als Faustregel: Reichen ein paar Deklarationen, genügt amsthm allein; thmtools kommt dazu, sobald das Zählen der \newtheorem-Klammern stört oder restatable-Sätze und ein Satzverzeichnis gewünscht sind.