プログラムが任意の大量のメモリを使用できるという理想的な見方をすれば、一般的なプログラミング言語はチューリング完全です。通常、孤立させることができる機能が1つもないため、これを使用しないと、言語はチューリング完全にはなりません。
直観的に言えば、チューリングの完全性には2つのことが必要です。
- 入力のサイズだけに依存しないメモリ量をプログラムが操作する方法。小さなオブジェクトから大きなオブジェクトを構築することができ、オブジェクト作成のいずれかの形式が適切である:オブジェクト、構造、ペア、リストは、
malloc
、new
、などであっても、スタックベースの割り当てが十分なアクセスオブジェクトへの道は上から任意の距離であることが提供されスタックの(スタックベースの割り当てとスタックのトップへのアクセスのみで、プッシュダウンオートマトンのみを取得します)。多くの弱い形式のデータ操作も適しています。たとえば、整数のサイズが制限されていないLispやPythonなどの言語では、基本的な整数演算だけでチューリングの完全性を十分に実現できます。
- プログラムがデータの一部に基づいて実行を継続または停止する方法。whileループでは、再帰と何らかの形の条件付き(例:
if
またはcase
/ switch
)とgoto
何らかの形の条件付きの3つが一般的な3つの方法ですが、他にもあります。
チューリング完全な言語を理解する最良の方法は、強力であるがチューリング完全ではない言語の例を見ることであると思います。そのような言語の2つの主要なファミリを示す2つの例を示します(制限付きメモリで動作する言語を除く)。
整数演算と配列を使用する命令型言語を検討しますが、ループ(for i = 1 to n
、i
ループ中に変更できない場所)のみであり、任意の(while)ループではなく、再帰はありません。BLOOPと初期バージョンのFORTRANがその例です。このような言語では、プリミティブな再帰関数(計算量が入力のサイズに制限されている関数)しか表現できません。計算時間の制限があるため、この言語はチューリング完全ではありません—任意の再帰関数を表現できません—
関数型言語は、すべての関数が終了することを制限する型システムを通じて再帰を制限することにより、非チューリング完全にすることができます。型システムが決定可能である場合(つまり、プログラムが適切に型指定されているかどうかを決定可能である場合)、そのような言語はチューリング完全であってはなりません(停止の問題が決定できないため)。CoqやAgdaなどの定理証明に使用される言語はこの種のものです。
チューリングの完全性を放棄することでイドリスができないことも参照してください。
余談ですが、定理の証明者は、ユーザーに終了証明を入力するように要求します(つまり、自分ではそれらを見つけられません)。したがって、定型証明システムを決定不能な型システムで作成することができます。正しい証明が受け入れられた場合、あなたは幸せです。それ以外の場合、しばらくするとあきらめます。しかし、それはユーザーフレンドリーではありません。ほとんどの定理証明者は決定可能な型システムを持っています。用語を入力すると、それが受け入れられるか、型エラーが返されます。定理の証明者が持っていないのは決定可能な型推論です。型情報の一部を含む用語を入力してそれが拒否された場合、その理由は型を入力できないためか、推論エンジンが十分に賢くないためかがわかりません。