証明の終わりに置く白い四角「□」は、実はフォントの文字ではありません。LaTeX の amsthm はあの記号を、縦罫線二本と横罫線二本を組み合わせて その場で描いて います(amsthm.sty の \openbox。実測で幅 7.77786pt・高さ 6.75003pt、10pt 本文なら 0.77778em × 0.675em)。定理環境も同じ発想でできています。LaTeX は「定理」という完成品を配るのではなく、\newtheorem という 宣言の仕組み だけを渡してきて、何を定理と呼び、どう番号を振るかは書き手が決めます。このページでは、\newtheorem が実際に何を生成するのか、二つの角括弧がなぜ併用できないのか、\theoremstyle が変えるもの、そして「証明 終わり 記号 位置」がずれる \qedhere の問題までを、実際に組んで確かめた結果とともに追います。
\newtheorem が生成するもの——環境とカウンタ
\newtheorem{theorem}{Theorem} は、環境をひとつと、それを数えるカウンタをひとつ 作ります。ログを見ると \c@theorem=\count196 のような行が出て、カウンタが実際に割り当てられたことが分かります。第一引数は本文で \begin{…} に書く環境名、第二引数は見出しに太字で印字される語です。この二つが別物であることが要点で、環境名は英字のまま theorem にしておき、印字される語だけを Satz や 定理 に差し替える、という運用ができます。
\usepackage{amsthm}
\newtheorem{theorem}{Theorem} % declares the environment AND allocates a counterこの宣言のあとで theorem 環境を使うたびに、「Theorem 1」「Theorem 2」と太字の見出しと通し番号が付き、なかの文は既定のスタイルでイタリックに組まれます。番号は LaTeX のカウンタが持っているので、途中に定理を挿入すれば以降が自動でずれます。「latex 定理 番号」で探して最初に効くのがこの性質です——番号を手で書かない限り、番号は絶対にずれません。
\begin{theorem}
There are infinitely many primes.
\end{theorem}
\begin{theorem}[Pythagoras]
In a right triangle, $a^2 + b^2 = c^2$.
\end{theorem}二つ目の例のように、\begin{theorem} の直後に角括弧で名前を渡すと、「Theorem 2 (Pythagoras).」のように番号のあとへ括弧書きで添えられます。これは 番号の有無とは独立 で、後述の \newtheorem* で作った番号なしの環境でも同じように使えます。なお \newtheorem 自体は 標準の LaTeX2e にも入っています。素の \newtheorem でも番号付き環境は作れますが、このあと扱う \theoremstyle・\newtheorem*・proof 環境・\qedhere はすべて amsthm の拡張で、\usepackage{amsthm} を書いて初めて使えます。
二つの角括弧——共有と従属は併用できない
\newtheorem は角括弧をひとつだけ受け取り、それを置く位置で意味が変わります。環境名の直後に置けば「既存のカウンタを共有する」、第二引数の後ろに置けば「その親カウンタに従属して番号がリセットされる」。定理と補題を別々に数えると「定理 1、補題 1、定理 2、補題 2…」と同じ番号が散らばって読者が迷うので、多くの数学書は前者を選んで「定理 1、補題 2、定理 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"同じ「後ろの角括弧」に section ではなく既存の定理環境を渡すこともできます。\newtheorem{corollary}{Corollary}[theorem] とすると、系の番号は 定理が現れるたびにリセット され、「Corollary 3.1」=「Theorem 3 に付いた最初の系」という読み方になります。
| 宣言 | 効果 |
|---|---|
\newtheorem{theorem}{Theorem} | 独自のカウンタで 1, 2, 3, … と通し番号を振る |
\newtheorem{lemma}[theorem]{Lemma} | theorem のカウンタを共有し、定理と補題が一本の番号列になる |
\newtheorem{theorem}{Theorem}[section] | \section ごとに 1 に戻り、節番号を前置して「2.1」の形で出る |
\newtheorem{corollary}{Corollary}[theorem] | theorem が出るたびリセットされ、親の定理番号を継いで「3.1」の形で出る |
\newtheorem*{remark}{Remark} | カウンタを作らず、番号なしで見出し語だけを印字する(amsthm が必要) |
では 両方を同時に 書いたらどうなるか。\newtheorem{lemma}[theorem]{Lemma}[section] を TeX Live 2024 で通すと、エラーは出ますが \newtheorem について何も言ってくれません。\newtheorem は二つ目の角括弧を読まないので、[section] がプリアンブルに ただの文字として取り残され、LaTeX は本文が始まったと勘違いします。出るのは次のメッセージです。
! LaTeX Error: Missing \begin{document}.
l.4 \newtheorem{lemma}[theorem]{Lemma}[
section]つまり、共有と従属は どちらか一方しか選べません。両方欲しいとき——「補題は定理と番号を共有し、その番号は節ごとにリセットされてほしい」——は、親のほうにだけ [section] を書きます。\newtheorem{theorem}{Theorem}[section] としておけば、\newtheorem{lemma}[theorem]{Lemma} で共有した補題も自動的に節番号つきになります。カウンタが一つしかない以上、これで矛盾なく両立します。
エラー Command \theorem already defined. が出たとき
このエラーは、同じ環境名を二度宣言した ときに出ます。\newtheorem は新しい環境を作る命令なので、既にある名前に上書きすることは許されません。プリアンブルに \newtheorem{theorem}{Theorem} を二回書いたときの出力がこれです。
! LaTeX Error: Command \theorem already defined.
Or name \end... illegal, see p.192 of the manual.実務でこれに当たるのは、たいてい自分で二回書いたからではありません。文書クラスや読み込んだパッケージが、すでに theorem を宣言している ためです。学会のテンプレート、amsart、elsarticle などは定理環境を先回りして用意していることがあります。対処は三つ。プリアンブルからその一行を消す、mytheorem のように名前を変える、あるいは既存の宣言をそのまま使って \theoremstyle だけ調整する。既存の環境の見出し語だけを変えたいなら、\newtheorem ではなく \renewcommand{\theoremname}{…} のようなクラス固有の方法を探すのが早道です。
\theoremstyle が変えるのは見出しと本文の書体
amsthm の \theoremstyle は、見出し(head)と本文(body)の 書体の組み合わせ を切り替えます。組み込みは plain・definition・remark の三つ。決定的に重要なのは、\theoremstyle{…} が その後に書いた \newtheorem にだけ効く ことです。宣言のあとにスタイルを置いても遡って適用されないので、プリアンブルではスタイルごとに宣言をまとめます。何も書かなければ plain です。
plain: 見出しは太字、本文はイタリック。定理・補題・命題・系など、強調して述べる主張に。何も指定しないときの既定。definition: 見出しは太字、本文は立体(ローマン体)。定義・例・問題・条件など、普通の文として読ませたいものに。数式や長い文が入るときは立体のほうが読みやすくなります。remark: 見出しがイタリック、本文は立体。注意・注記・claim など、控えめに添える文に。見出しまで細くなるので、本文の流れを邪魔しません。
\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}この構成では、theorem・lemma・corollary・definition・example の五つが節ごとの一本の番号列(Theorem 2.1、Definition 2.2、Lemma 2.3…)を共有し、前三つは本文がイタリック、後二つは立体になります。remark だけは番号を持たず、見出し「Remark」がイタリックで出ます。番号を共有しながら書体だけ分けられるのは、カウンタとスタイルが独立した二つの軸 だからです。
proof 環境と、証明 終わり 記号 位置がずれる問題
amsthm の proof 環境は、冒頭にイタリックの見出し「Proof.」を置き、末尾に \qedsymbol(既定は □)を自動で付けます。ところが proof は記号を 最後の段落の行末 に置こうとするため、証明が別行立ての数式で終わると行き場を失い、□ が 独りぼっちで次の行に落ちます。これは印象ではなく寸法で確認できます。同じ証明を \vbox に入れて高さを測ると、こうなりました。
% \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 saved差は 19.16667pt、ちょうど一行分です。\qedhere は「記号をここに置け」という指示で、別行立ての数式の末尾に書けば □ がその数式の行の右端に収まり、余分な一行が消えます。\qedhere は equation・align・gather* などの数式環境でも、enumerate の最後の項目でも動きます(TeX Live 2024 でいずれもエラーなく通ることを確認しました)。置き場所に困る箇所では amsthm が Package amsthm Warning: The \qedhere command may not work correctly here と警告してくるので、ログを見れば分かります。
\begin{proof}
Rearranging both sides gives
\[
a^2 + b^2 = c^2. \qedhere
\]
\end{proof}見出しの語と終了記号は、どちらも差し替えられます。個々の証明には \begin{proof}[Proof of Theorem 1] のように角括弧で見出しを渡せますし、文書全体の既定語は \proofname を再定義して変えます(\renewcommand{\proofname}{Demonstration} とすれば見出しが「Demonstration.」になることを確認しました)。終了記号は \qedsymbol の再定義です。冒頭で触れたとおり、既定の \qedsymbol は \openbox——罫線で描いた白い四角——なので、$\blacksquare$ に差し替えれば黒い四角に、空に再定義すれば記号そのものが消えます。ただし \blacksquare は amssymb(amssymb.sty の 48 行目)の記号なので、amsthm だけでは ! Undefined control sequence. になります。\usepackage{amssymb} を忘れないでください。
\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——角括弧の位置を key=value に置き換える
宣言が十を超えるころには、「角括弧の位置で意味が変わる」という \newtheorem の作法は読みにくくなります。thmtools(TeX Live 2024 同梱は 2023/05/04 v0.76)は amsthm(や ntheorem)の上に載る上位インターフェースで、\declaretheorem によって同じ設定を key=value で書けるようにします。番号の実体を持たず、裏側で amsthm の \newtheorem を呼ぶだけなので、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}キーの対応は素直です。節への従属が numberwithin=(同義語 parent=・within=)、カウンタの共有が sibling=(同義語 numberlike=・sharecounter=)、番号なしが numbered=no、見出し語が name=(同義語 title=・heading=)、体裁が style=。上のプリアンブルを実際に組むと、Theorem 1.1 に続いて Lemma 1.2 が出ます——sibling= が確かに一本の番号列を作っていることが出力で確かめられます。
thmtools を入れる本当の理由は、amsthm 単体では面倒な二つの機能です。ひとつが 再掲(restatable)。同梱の thm-restate を読み込み、定理を restatable 環境で書くと、その中身がマクロとして保存され、あとから 同じ番号のまま もう一度組めます。主張は本編に番号付きで置き、証明だけ付録に回したいときの定石です。実際に組むと、本編の Theorem 1.1 が付録でもそのまま 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 の第一引数(省略可)は名前、第二が使う定理環境、第三が 内容を覚えておくマクロ名 です。あとで \firsteuclid を展開すればその定理がもう一度組まれ、番号は最初の出現に固定されたままになります。星を付けた \firsteuclid* は、\label/\ref の行き先を 再掲側ではなく元の宣言側 に向けたまま再掲する形です。もうひとつの機能が 定理一覧。\listoftheorems と書けば目次のような一覧が生成され、ignoreall と show={…} で載せる環境を絞れます。\begin{…}[名前] で名前を付けた定理だけを拾う onlynamed もあり、hyperref を併用していれば各項目が本体へのリンクになります。
\listoftheorems % everything
\listoftheorems[ignoreall, show={theorem, lemma}] % only these two
\listoftheorems[ignoreall, show={theorem}, onlynamed] % only the ones you named体裁を自作したいときは \declaretheoremstyle で新しいスタイルを定義し、\declaretheorem[style=…]{…} から呼び出します。見出しの書体 headfont、本文の書体 bodyfont、前後の空き spaceabove・spacebelow、名前を囲む括弧 notebraces、見出しと本文のあいだ postheadspace、終了記号 qed などをキーで指定できます。判断としては、宣言が数個で済むなら amsthm だけで十分、\newtheorem の角括弧を数えるのが苦になってきたか、restatable と定理一覧が欲しくなったら thmtools を足す、という順序が無理がありません。