マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

TeX でもっともっと Quine する話(1)

前回の記事では次のようなタイプの「TeX 言語の Quine」を作った。

元の TeX 文書ファイルと生成される PDF ファイルの内容がバイナリで一致する。

しかしこれは pdfTeX エンジンを使うことを前提としている。「(Knuth の)元祖 TeX」で同様のことはできないだろうか。もちろん、元祖 TeX が出力するのは DVI ファイルだから、Quine の要件は次のようになる。

元の TeX 文書ファイルと生成される DVI ファイルの内容がバイナリで一致する。

本記事では「DVI で Quine する」ことについて考察する。

DVI で Quine できない話

いきなり残念な話になるが、“普通の”TeX を使うのでは「DVI で Quine する」ことは不可能である。

DVI ファイルフォーマットの定義を読めば解るが、現状の TeX エンジンが出力する DVI ファイルの先頭 10 バイトは必ず次の値になっている。

F7 02 01 83 92 C0 1C 3B 00 00

だから「(先述の意味で)Quine である TeX 文書ファイル」があるとすると、その先頭は必然的にこの 10 バイトになる。これを TeX エンジンに入力するとどうなるか。

まずは LaTeX の場合を考えてみよう。LaTeX では 0xF7 のカテゴリコードは 12(通常の文字)、だから先頭の 0xF7 でいきなり段落を始めようとするが、\begin{document} が現れる前なのでこれは当然エラーになる。従って、LaTeX 文書としては通らない。

plain TeX の場合はどうか。plain でも 0xF7 は通常文字であり、plain ではいきなり段落を始めることが許されるのでこれは大丈夫である。*1次の 0x02 も通常文字である。ところがその次の 0x01 のカテゴリコードはなんと 8(下添字)である。plain.tex でそう定められているのである。*2

[plain.tex 17行目]
\catcode`\_=8 \catcode`\^^A=8 % underline and downarrow are for subscripts

つまり、0x01 の文字は plain TeX では _ と同等ということである。周知の通り、_ が数式モードの外で現れるとエラーになる。だから“普通の”plain TeX に DVI ファイルを入力すると、この 0x01(^^A)の箇所でエラーになって通らないのである。

! Missing $ inserted.
<inserted text>
                $
<to be read again>
                   ^^A
l.1 ^^f7^^B^^A
              ^^83^^92^^c0^^\;^^@^^@^^@^^@^^C^^e8^^[ TeX output 2016.01.05:1...

つまり“普通の”plain TeXLaTeX では「DVI で Quine する」ことは無理なのである。

続く

*1:ただしデフォルトのフォントである cmr10 は文字コード 0xF7 のグリフを持たないので、警告が発生することになる。

*2:文字コード 0x01 が何故“downarrow”〈↓〉なのか、という謎は TeXbook の付録 C を読めば解る。