テキストエディタで式変形する人向けの数式マークアップのアイデア
きっかけ
マークアップ言語を「人間には冗長だけど表現力が高くパースしやすい」と「人間が読み書きしやすいけど表現力は低い」の軸で考えた時、HTMLとかLaTeX文章にはMarkdownとかの対応物がいっぱいあるけど、LaTeX数式に対応する有名なのって無いよなあ、ということを考えれいた。俺が知らないだけ?
— ハヤテマル (@h8t0) January 9, 2023
背景
僕は字が汚い。手書きで式変形していると5秒前に自分で書いた記号が読めないということがしょっちゅうある。なので複雑な式変形を考えるときは手書きノートを使わず、テキストエディタ上のLaTeXコードを編集しながら考える。Twitterを見るに似たようなことをやっている人はけっこういるらしい。
この方式の最大の利点はコピペが使えることである。例えば数式中の二項が打ち消し合うようなとき、行を丸ごとコピペしてから打ち消し合う部分を削除するといったことができる。数式中のパーツをコピペして使い回せるのも嬉しい。そして何より過去に書いた数式が読めないというリスクが無い。書いた数式がそのまま論文やブログなどで使えるというのも時間短縮になって嬉しい。
問題点として、一見しただけでは数式のイメージが掴みにくいということがある。\frac{\sqrt{\pi}}{2}という数式をLaTeXで書くと\frac{\sqrt{\pi}}{2}
のようになるが、このコードを見て\frac{\sqrt{\pi}}{2}という「形」を脳内でレンダリングするのには時間がかかってしまう。これは式変形のインスピレーションが浮かびにくくなることにも繋がる。
リアルタイムで数式のプレビューができるようなツールを使うというのが一つの解決策として考えられるだろう。しかしコードのどの部分が数式のどの部分に対応するかがすぐに把握できないと、先に述べたコピペが使えるといった利点を活かしにくい。
数式というものはネストした構造を持っており、これをテキストベースで表現するためには括弧や専用キーワードなどのブロックを明示する仕組みが必要になる。これらが見た目のノイズになり、コードから数式をイメージするのを妨げてしまう。ある程度複雑な数式になると括弧まみれになってしまい、書いているときはまだ良いが読んで数式をイメージするのがものすごく大変になってしまう。これはAsciiMathのようなeasy-to-writeであることを重視した数式マークアップ言語を使ったとしても避けることができない問題である。
アイデア
括弧まみれになるのがつらいのであれば、括弧の代わりにインデントを使うオフサイドルールを採用するというのはどうだろうか。試しに
\frac{a^{b^c}_{d_{e,f}}}{g}
という数式をインデントで表現することを考えてみると
frac subsup a sup b c sub d concat e , f g
または
a _ b _ c ^ d ^ e , f / g
という感じになるだろうか。
このままだと読みにくいので、インデントを.
で表し、コードを1行にまとめてみる。
..a ._ ...b .._ ...c .^ ...d ..^ ....e ...., ....f / .g
このままだと、結合が強い部分にたくさんの.
が入ることになり違和感があるので、数の大小を逆転させることにすると
..a ..._ .b .._ .c ...^ .d ..^ e , f ..../ ...g
となる。結合の優先順位が低いときには.
を入れる、と考えると理解しやすくなった気がする。実は式の解釈を変えないように不要な.
を削除することができて
a ._b_c .^d^e,f ../ g
のようになる。ここまで来ると、それなりに使いやすい文法に見えてくる。とはいえ全てをこの記法で表現するというのは辛いだろう。しかし、括弧を使ったグルーピングと併用して、ネストが深くなり括弧まみれで数式の構造が読み取りにくくなるときにそれを緩和する、といった運用ができれば案外使い所があるのではないだろうか。
具体例
\sum_{ \sum_{j_i,l} n^{k_\mathrm{ABC}+1}_{j_i-1,l} = N_l } j_i^l
という数式を考えてみる。
- LaTeX:
\sum_{ \sum_{j_i,l} n^{k_\mathrm{ABC} +1}_{j_i -1,l} = N_l } j_i^l
- LaTeX+Unicode:
Σ_{ Σ_{j_i,l} n^{k_\mathrm{ABC}+1}_{j_i -1,l} = N_l } j_i^l
- AsciiMath:
sum_( sum_(i_j, l) n_(i_j -1,l)^(k_"ABC" +1) = N_l ) j_i^l
- AsciiMath+Unicode:
Σ_( Σ_(i_j, l) n_(i_j -1,l)^(k_"ABC" +1) = N_l ) j_i^l
- dot:
Σ.._ Σ._ i_j,l . n._ i_j-1,l .^ k_"ABC"+1 .= N_l .. j_i^l
- hybrid:
Σ_( Σ._ i_j,l. n._ i_j-1,l .^ k_"ABC"+1 .= N_l ) j_i^l
正直何とも言えない感じだな…ドットが二連続してしまうとかえって脳への負荷がでかくなってしまう。x_{y_z}みたいな数式をx._y_z
と書いてしまえるのはいい感じな気がする。
例が些か人工的すぎるのかもしれない。一応前に書いた論文の式の一部を持ってきて少し弄ったやつではあるのだけど…
まとめ
数式マークアップが括弧まみれになってしまってつらい問題をドットを用いた簡易的な記法を導入することで緩和するというアイデアが閃いた。個人的な用途で色々試してみて、実際に便利かどうか検討してみたい。
適当にLaTeX数式に変換する処理系を作るのも面白いかも。その場合どうやって処理するのが良いのか気になっていたが、オフサイドルールのある言語では字句解析のときにインデントを専用のトークンINDENT
,
DEINDENT
などに置き換えて、構文解析時にこれらを括弧と同様に扱えばできるようだ。
おわり。