この課題の目標は、(最終的に)選択した言語で停止可能なすべてのプログラムを出力することです。最初はこれは不可能に思えるかもしれませんが、実行順序を非常に慎重に選択することでこれを実現できます。
以下は、これを説明するためのASCIIダイアグラムです。列は、考えられるすべてのプログラムの番号付けを表します(各プログラムは、有限のアルファベットからの有限数のシンボルです)。各行は、そのプログラムの実行における特異なステップを表します。X
その時間ステップにおいてそのプログラムによって実行される実行を表します。
step# p1 p2 p3 p4 p5 p6
1 X X X X X X
2 X X X X X
3 X X X X
4 X X X X
5 X X X
6 X X
7 X X
8 X X
9 X X
∞ X X
おわかりのように、プログラム2と4は停止しません。それらを一度に1つずつ実行すると、コントローラーはプログラム2である無限ループに陥り、プログラム3以降を出力することはありません。
代わりに、ダブテールアプローチを使用します。文字は、最初の26ステップの実行可能な順序を表しています。*
Sは、そのプログラムが停止したと出力される場所です。.
sがまだ実行されていない段階です。
step# p1 p2 p3 p4 p5 p6
1 A C F J N R V
2 B E I M Q * Z
3 D H * P U
4 G L T Y
5 K O X
6 * S .
7 W .
8 . .
9 . .
∞ . .
ターゲット言語の要件
ターゲット言語(並列解釈される言語)はチューリング完全でなければなりません。それ以外に、チューリング完全な言語であれば、はるかに大きな言語のチューリング完全なサブセットを含むことができます。また、サイクリックタグシステムルールなどを自由に解釈できます。チューリング完全である理由を示すことができれば、テストする言語を作成することもできます。
例として、brainfuckをテストすることを選択した場合[]-+<>
、入力のみがサポートされず、出力が破棄されるだけなので、サブセットのみをテストするのが最善です(以下を参照)。
「あなたがゴルフをしている」「コントローラー」プログラムに関しては、特別な要件はありません。通常の言語制限が適用されます。
プログラムの無限リストを作成する方法
プログラミング言語の大部分は、有限のアルファベットからの一連の記号として表すことができます。この場合、考えられるすべてのプログラムのリストを長さの順に列挙するのは比較的簡単です。使用するアルファベットは、ターゲット言語の要件を代表するものでなければなりません。ほとんどの場合、これは印刷可能なASCIIです。ご使用の言語が追加機能としてUnicodeをサポートしている場合、Unicode文字の可能な組み合わせすべてをテストするのではなく、ASCIIのみをテストする必要があります。言語でのみ使用する[]-+<>
場合は、「コメント」ASCII文字のさまざまな組み合わせをテストしないでください。APLのような言語には、独自の特別なアルファベットがあります。
FractranやTuring Machinesのように、言語がアルファベット以外の方法で最もよく記述されている場合、有効なすべての有効なプログラムのリストを生成する他の同等の有効な方法があります。
増え続けるプログラムのリストの解釈
この課題の重要な部分は、増え続けるプログラムのリスト用の並列インタープリターを作成することです。これにはいくつかの基本的な手順があります。
- 有限数のプログラムをリストに追加します
- リスト上の各プログラムを一定期間、個別に解釈します。これは、それぞれに対して1つの命令ステップを実行することで実現できます。すべての状態を保存します。
- リストからすべての終了/エラースロープログラムを削除します
- 完全に停止した*プログラムを出力する
- さらにプログラムをリストに追加します
- 各プログラムを順番にシミュレートし、中断したところから古いプログラムの実行を再開します
- リストからすべての終了/エラースロープログラムを削除します
- 完全に停止した*プログラムを出力する
- 繰り返す
*正常に停止するプログラムのみを出力する必要があります。 これは、実行中にスローされる構文エラーやキャッチされない例外がなかったことを意味します。入力を要求するプログラムも、出力せずに終了する必要があります。プログラムが出力を生成する場合、それを終了するのではなく、出力を破棄するだけです。
その他のルール
- テストしたプログラムを含めるために新しいスレッドを生成しないでください。これにより、並列化の作業がホストOS /他のソフトウェアにオフロードされます。
- 編集:潜在的な将来の抜け穴を閉じるために
eval
、テストされたプログラムのコードの一部(または関連する機能)を許可されていません。あなたはできeval
インタプリタのコードからコードブロックを。(BF-in-Pythonの答えは、これらのルールの下でも有効です。) - これはコードゴルフです
- 提出物を書く言語は、テスト/出力している言語と同じである必要はありません。
- 使用可能なメモリには制限がないと想定する必要があります。
- チューリング完全性を証明する場合、入力はプログラムにハードコーディングされ、プログラムの内部状態から出力を読み取ることができると想定できます。
- プログラムがそれ自体を出力する場合、それはおそらく間違っているか、多言語です。
"If your program outputs itself, it is probably wrong or a polyglot."