本文へスキップ
totonoe.tech

難解プログラミング言語を整える

中級

Malbolgeを整える。

= 「人間には書けない」よう設計された言語の、既知のプログラムを動かしてレジスタの動きを見る

Malbolge が初めての方は、先に そもそも Malbolge とは・何の役に立つのか をどうぞ。

① 既知のプログラムを実行

Malbolgeは人が書けないため、このページでは検証済みのプリセットのみを用意しています。

Malbolge ソース(プリセットの選択・貼り付け用) 送信ゼロ。空白・改行は命令の位置カウントに数えません

結果(out命令の出力)

実行するとここに出力が表示されます

次に実行される命令((c+その位置の値) % 94 で決まります)

まだ読み込んでいません。「1ステップ進める」を押すと表示されます。

レジスタ a(アキュムレータ)

0

レジスタ c(コードポインタ)

0

レジスタ d(データポインタ)

0

ステップ数 / 状態

0

そもそも Malbolge とは

「人間に書かせない」ことを目指して設計された言語。

Malbolge(マルボルジェ)は、1998年に Ben Olmstead が発表した言語です。名前はダンテの『神曲』に出てくる地獄の一つに由来します。できるだけプログラムを書きにくくすることを目的に作られ、命令は文字そのものではなく、置かれた位置との組み合わせで決まります。しかも実行のたびに、自分のコードが書き換わっていきます。

あまりに難しいため、最初のプログラムが動いたのは公開からしばらくたってからで、人が手で書いたものではなく、コンピューターによる探索で見つけられたと言われています。ふつうの言語が「書く人を助ける」ように作られるのと正反対で、書く人を困らせるための設計という点が最も違います。

何の役に立つのか

  • 「良い言語とは何か」を逆から考えられる

    書きやすさを妨げる仕掛けを並べた言語なので、ふつうの言語がどんな工夫で書きやすくなっているかが見えてきます。

  • 自己書き換えと符号化の考え方に触れられる

    実行のたびに命令の意味が入れ替わる仕組みは、暗号や難読化の考え方に通じます。

  • プログラムを「探索で作る」発想を知る

    人が書けないなら、コンピューターに探させるという研究的な遊びがあります。

  • 実行環境を正確に作る腕試しになる

    仕様が癖だらけなので、1つ1つ正しく実装すること自体が良い練習になります。

  • 研修のアイスブレイクになる

    「書けるものなら書いてみて」という言語は、プログラミングの難しさを笑って話すきっかけになります。

知っておくと面白いこと

  • ふつうは同じ文字なら同じ命令ですが、Malbolge は置かれた位置によって、同じ文字でも命令が変わります。
  • 数は2進数ではなく3進数の10桁で扱います。ふつうのコンピューターの感覚とはずれた世界です。
  • そのため、このページでは自分で書くより、検証済みの既知のプログラムを動かして仕組みを眺めるのが中心です。

上の実行環境でプリセットを動かし、レジスタとステップ数の動きを見ると、この言語の独特さが伝わります。

解説

なぜMalbolgeは「人間には書けない」と言われるのか。

Malbolgeは1998年、Ben Olmsteadが発表した言語です(esolangs.org: Malbolge)。名前はダンテ「神曲」の地獄の第八圏(Malebolge)に由来します。世界初のHello Worldプログラムは、人が書いたのではなく、Lisp製の局所ビームサーチ(あり得るプログラムの空間を機械的に探索するプログラム)によって発見されました。

仕組みが難解な最大の理由は2つです。1つめは、メモリ上のある位置に置かれた文字が「その文字コード」ではなく「(その位置+文字コード) % 94」という計算結果で命令が決まること。同じ文字でも置く位置がずれれば別の命令になります。2つめは、命令を1つ実行するたびに、実行した場所の中身が暗号表で自動的に書き換わること(自己書き換え)。プログラムは実行しながら自分自身を変化させ続けるため、事前に「このプログラムはこう動く」と読み解くのが極めて困難です。

(c+[c])%94 名前 動き 意味
4 jmp C = [D] Dが指すメモリの値をCへ代入する(ジャンプ)
5 out print(A % 256) Aの値を文字コードとして出力する
23 in A = 入力 入力を1文字読みAへ(本ページは入力なし=常にEOF扱い)
39 rotr A = [D] = rotate_right([D]) Dが指す値を3進数で右に1桁回転し、その結果をAにも入れる
40 mov D = [D] Dが指すメモリの値をDへ代入する
62 crz A = [D] = crazy(A, [D]) AとDが指す値の「crazy演算」(後述の表)を行い、結果をAにもDが指す先にも入れる
68 nop (何もしない) 何もしない
81 end STOP 実行を停止する

レジスタは3つ(a=アキュムレータ、c=命令の実行位置、d=データの参照位置)で、メモリは59,049(3の10乗)個の升目、各升目は0〜59,048の10桁の3進数です。8命令のいずれにも当てはまらない値は何もしない命令(NOP)として扱われます。

あわせてエソラング図鑑(Malbolgeの「読み物」としての解説も掲載)やBrainfuckの遊び場もどうぞ。

送信ゼロ(貼り付けたコードはこの端末から出ません)。入力を読む命令(in)はこのページでは常に「入力なし(EOF)」として扱われます。実行はステップ数の上限に達すると自動的に停止します。

このツールについて

Malbolgeは「解読を目的として設計された」言語です。命令は文字そのものではなく (実行位置 + そこに置かれた文字コード) % 94 で決まり、しかも実行のたびに実行した命令自身を暗号表で書き換えます。同じ文字でも位置が変われば意味が変わるため、人間が新規にプログラムを書くのは事実上不可能で、実在するプログラムはビームサーチなどの探索やツールで発見・生成されたものです。このページは実行専用(生成機能はありません)。

世界初の Hello World は人間ではなく探索プログラムが発見した、というエピソードで有名な言語。既知の正しいプログラムを動かして、a/c/d レジスタとステップ数の推移を見られます(新規作成の機能はありません)。

主な機能

  • 既知の Hello World 2種をプリセット実行
  • 1ステップ実行でレジスタ(a/c/d)を確認
  • 自己書き換え・crazy 演算を仕様どおりに実装
  • 実行専用(生成なし)・送信ゼロ
  • 次に実行される命令を (c+値)%94 の計算つきで表示

よくある質問

Q. なぜ Malbolge は人間に書けないと言われるのですか?

A. 命令が文字そのものではなく「(実行位置+文字コード)÷94 の余り」で決まることと、命令を実行するたびにその場所の中身が暗号表で書き換わる(自己書き換え)ことの2点が理由です。同じ文字でも位置がずれれば別の命令になり、実行しながら自分自身が変化し続けます。

Q. 世界初の Hello World は誰が書いたのですか?

A. 人が直接書いたのではなく、Lisp で書かれた局所ビームサーチ(あり得るプログラムの空間を機械的に探索するプログラム)が発見しました。このページのプリセットにその元祖プログラムを収録しています。

Q. なぜこのページには新規作成の機能が無いのですか?

A. 自己書き換えと位置依存の命令のため、狙った動作を人が予測して書くことが事実上不可能だからです。実在するプログラムのほぼすべてが探索や専用ツールで発見・生成されたものです。

Q. レジスタ a・c・d は何をしていますか?

A. a は計算用の値を1つ持つアキュムレータ、c は今実行している命令の位置、d は読み書き対象のデータの位置です。いずれも0〜59,048の10桁3進数です。

Q. 入力を使うプログラムは動きますか?

A. 動きません。このページは入力欄を持たないため、入力命令は常に「入力なし」として扱われます。

入力値はURLの「#」以降に入るためサーバーには送信されません。リンクを開くと同じ状態を復元します。

続けて整える

運営サイト

私たちが運営するサイト