Hatena::ブログ(Diary)

マクロツイーター このページをアンテナに追加 RSSフィード Twitter

2012-04-11

\middle であり \mid であるもの

「集合の内包的記法」で用いる縦棒で \middle を利用する方法について。

周知の通り、LaTeX の数式においては、この縦棒は普通の | ではなく \mid という命令で表記される。\mid は (La)TeX で「関係演算子(relational operator)」という扱いになっていて、このため縦棒の前後の空きが適切に調整される。

\[ G = \{ (x,y) \in \mathbb{R}^2 \mid x^2 + y^2 = Z \} \]
f:id:zrbabbler:20120414130943p:image

この表記において外側の括弧が \left/\right で伸張されている場合、縦棒をそれに合わせて伸張させる必要があり、それに \middle を使いたい。ところが、生憎 \middle\mid とすることはできず(エラーになる)、代わりに \middle| と書くと、これは「関係演算子」の扱いにならないので失敗してしまう。

\[ G = \left\{ (x,y) \in \mathbb{N}^2 \middle|
        Z - \frac{1}{2} \leq x^2 + y^2 \leq Z + \frac{1}{2} \right\} \]
f:id:zrbabbler:20120414130942p:image

勿論、数式用空き命令を用いて手動で調整する、すなわち、\middle| の前後に \;(関係演算子前後の空き)を入れると正しい出力になることは確かである。しかしこのような手動の調整は避けたい人もいるだろう。何とかして「関係演算子扱いの \middle|」を出力する命令を作れないだろうか。*1

\middle\mid ができないのは \middle が予め「伸張できる」と定めたものにしか付けられないからである。*2それでは、\middle| に何か設定して「関係演算子扱いに変える」ことはできないか。実は、「関係演算子扱いにする」ためのプリミティブ \mathrel というのが存在する。*3

$I \heartsuit U$\qquad $I \mathrel{\heartsuit} U$
f:id:zrbabbler:20120414130941p:image

しかし、残念ながら、\mathrel{\middle|} とはできない。\mathrel{...} で囲った部分は外側の数式とは別扱いになるからである。*4

TeX.SX を探してみると、次のような答えが見つかる(How to get a \mid binary relation that grows… のページ;回答者は Philippe Goutet)。

% プリアンプルで以下を定義
\newcommand{\relmiddle}[1]{\mathrel{}\middle#1\mathrel{}}
% \middle の代わりに \relmiddle を付ける
\[ G = \left\{ (x,y) \in \mathbb{N}^2 \relmiddle|
        Z - \frac{1}{2} \leq x^2 + y^2 \leq Z + \frac{1}{2} \right\} \]
f:id:zrbabbler:20120414130940p:image

典型的な「ゴースト*5」を使った解決法であり、検証してみたが問題は見つからなかった。なので、「\middle\mid」を欲する人はこれを使うとよいであろう。

*  *  *

……ここからは TeX 屋向けの余談。実は上の定義について疑問に思うことがある。上の説明で、\middle を付けたものは「関係演算子\mathrel)」でないと述べた。ではそれの数式クラス(math class)は何だろうか。普通に考えると、「通常の文字(\mathord)」であるように思える。ところが、もし仮にそれが正しいとすると、上述の \relmiddle は正しい出力にならないはずである。

% \mathord である〈|〉の前後に \mathrel{} を置いてみる
\[ A \mid B  \qquad A \mathrel{}|\mathrel{} B \]
f:id:zrbabbler:20120414131343p:image

右側の式では縦棒の前後に \; 2 個分の空きが空いている。この理由は明らかで、もし A \mathrel{?}| ならば A と縦棒の間\; の空きが 2 個あるのは当然で、それと同じことが起こっている。ゆえに、もし \middle| が「通常の文字(\mathord)」であるとすると、\relmiddle| の前後の空きも 2 倍になってしまう。

以上から、\middle|\mathord でないことが解る。さらに調べると奇妙なことが明らかになる。

\[ \left\{ A \mathrel{}\middle|\mathrel{} B \right\} \]

上のソースと、中にある \middle を 8 つある数式クラス(\mathXXX*6)の各々に置き換えたもの(縦棒をそのクラスに変更したことになる)の出力を比べてみる。結果は、\middle| と出力が一致するのは \mathrel| しかない。しかし、\middle|\mathrel ではないことは既に確かめた。結局、\middle| はどの数式クラスでもないことになる。何か腑に落ちない。

[2012-04-13 追記]気になって夜眠れなくなった人は、H7K さんのコメントを参照。

*1:なお、関係演算子であっても前後の文字によっては空白が入らない場合もあるので、単純に \;\middle|\; に展開ざれるマクロを作るのは正解ではない。といっても、これで間に合わないような例で実際に起こりそうなものが思いつかないのだが……。

*2:なお、\mid を「\middle が付けられる」ように再定義することは可能だが、いずれにしても、\middle を付けると「関係演算子」扱いでなくなってしまう。ちなみに、\left を付けたものは必ず「開き括弧」扱いとなり、\right を付けたものは必ず「閉じ括弧」扱いになる。

*3:従って、\mid\mathrel{|}同値である。しかし先述の \middle の性質ゆえ、\middle{\mathrel{|}}\middle\mathrel{|} はエラーである。

*4:同じ理由で \left\{...{\middle|}...\right\} も不正である。

*5:前後の物に対して自分が『ある性質』をもつ如く振る舞いたい場合に、自分の前後に「何も出力しない『ある性質』をもつもの」(この場合 \mathrel{})を配置する、という手法

*6:通常の文字(\mathord)、大型演算子\mathop)、二項演算子\mathbin)、関係演算子\mathrel)、開き括弧(\mathopen)、閉じ括弧(\mathclose)、句読点\mathpunct)、内部数式(\mathinner)の 8 種類。

H7KH7K 2012/04/12 12:10 「左側は \mathclose,右側は \mathopen」という動作になっているようです.意図は分かりませんが,TeX82 のコードからの改造量を減らしたかったからではないでしょうか?

zrbabblerzrbabbler 2012/04/13 21:26 なるほど! これは予想外でした。
確かに、Dirac 記法(bra-ket)だとそれが適用なんですね。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/zrbabbler/20120411/1334151482