例1.レポートのページ数はいくつですか。
プログラムを学んでいたとき、データからきれいなレポートを印刷するツールを作って遊んでいました。明らかに、私はそれが本当に柔軟で強力であることを望んでいたので、すべてのレポートジェネレーターを終了するのはレポートジェネレーターになるでしょう。
レポートの定義は非常に柔軟であるため、チューリング完全でした。変数を調べたり、選択肢から選択したり、ループを使用して繰り返したりすることができます。
レポートインスタンスのページ数である組み込み変数Nを定義したので、各ページに「Nのページn」という文字列を配置できます。2つのパスを実行しました。最初のパスはページをカウントし(Nがゼロに設定されている間)、2番目のパスは最初のパスから取得したNを使用して実際にページを生成しました。
最初のパスでNが計算され、次に2番目のパスで異なるページ数が生成される場合があります(ゼロ以外のNは、レポートの動作を変更するため)。Nが落ち着くまでパスを繰り返してみました。それで、落ち着かなかったらどうなるので、これは絶望的だと気づきました。
これにより、「レポートが生成するページ数の安定した値が反復で確定しない場合は、少なくともユーザーを検出して警告できますか?」という質問につながります。幸いなことに、この時までに私はチューリング、ゲーデル、計算可能性などについて読むことに興味を持ち、つながりを築きました。
数年後、MSAccessが「6/5ページ」を印刷することがあることに気づきました。これは本当に素晴らしいことです。
例2:C++コンパイラ
コンパイルプロセスには、テンプレートの拡張が含まれます。テンプレート定義は、複数の専門分野(「条件」として機能するのに十分)から選択でき、再帰的にも使用できます。つまり、これはチューリング完全(純粋な関数型)メタシステムであり、テンプレート定義は言語であり、型は値であり、コンパイラーは実際にはインタープリターです。これは事故でした。
したがって、特定のC ++プログラムを調べて、プログラムのコンパイルが成功したときにコンパイラが原則として終了できるかどうかを判断することはできません。
コンパイラベンダーは、テンプレート再帰のスタック深度を制限することでこれを回避します。深さはg++で調整できます。