制約された入力または予測可能な入力がある場合、停止の問題を解決することは可能ですか?


18

停止の問題は一般的なケースでは解決できません。許可された入力を制限する定義済みのルールを考え出すことは可能ですが、その特殊なケースでは停止の問題を解決できますか?

たとえば、たとえばループを許可しない言語は、プログラムが停止するかどうかを非常に簡単に判断できるようです。

私が今解決しようとしている問題は、プログラムの妥当性をチェックするスクリプトチェッカーを作成しようとしていることです。非常に予測可能な入力を意味するスクリプトライターに何を期待するかを正確に知っていれば、停止する問題を解決できます。これを正確に解決できない場合、これを解決するための優れた近似手法は何ですか?

回答:


10

直感的な答えは、無制限のループがなく、再帰がなく、gotoがない場合、プログラムが終了するということです。これは完全に真実ではありません。他の方法で非終了をこっそりする方法がありますが、ほとんどの実用的なケースには十分です。もちろん逆は間違っています。これらの構成要素には、終了しないプログラムを許可しない言語がありますが、洗練された型システムなどの他の種類の制限を使用します。

再帰

スクリプト言語の一般的な制限は、再帰を動的に防止することです。AがBを呼び出し、Cが呼び出し...がAを呼び出す場合、インタープリター(または、チェッカー)は、再帰が実際に終了する可能性がある場合でも、あきらめるかエラーを通知します。2つの具体例:

  • Cプリプロセッサは、マクロを展開している間、マクロをそのまま残します。最も一般的な使用法は、関数のラッパーを定義することです:

    #define f(x) (printf("calling f(%d)\n", (x)), f(x))
    f(3);
    

    これは

    (printf("calling f(%d)\n", (3)), f(3))
    

    相互再帰も同様に処理されます。その結果、Cプリプロセッサは常に終了しますが、実行時の複雑さの高いマクロを構築することは可能です。

    #define f0(x) x(x)x(x)
    #define f1(x) f0(f0(x))
    #define f2(x) f1(f1(x))
    #define f3(x) f2(f2(x))
    f3(x)
    
  • Unixシェルはエイリアスを再帰的に展開しますが、既に展開されているエイリアスに遭遇するまでです。繰り返しますが、主な目的は、同様の名前のコマンドのエイリアスを定義することです。

    alias ls='ls --color'
    alias ll='ls -l'
    

nn

再帰呼び出しが終了することを証明するより一般的な手法があります。たとえば、ある再帰呼び出しから次の呼び出しに常に減少する正の整数を見つけるなどですが、これらの検出はかなり困難です。推測することはもちろん、検証するのが難しいことがよくあります。

ループ

formn

特に、forループ(および条件などの合理的な言語構成要素)を使用すると、すべてのプリミティブな再帰関数を記述できます。プリミティブな再帰関数は、whileループやgoto、再帰、その他のトリックを使用しないため、構文的に(難読化されていない方法で記述されている場合)認識できます。プリミティブな再帰関数は終了することが保証されており、ほとんどの実用的なタスクはプリミティブな再帰を超えません。


4

TerminatorおよびAProVeを参照してください。彼らはヒューリスティックに依存する傾向があり、それらが動作するプログラムのクラスを明確に説明しているかどうかはわかりません。それでも、それらは最先端のものとみなされているので、あなたにとって良い出発点になるはずです。


4

はい、可能です。このような問題を解決する一般的な方法の1つは、入力の一部としてコードに依存する余分な(単調な)計算不可能なパラメーターを考慮することです。そのパラメーターを持つ問題の複雑さを大幅に減らすことができます。

パラメーターを計算することはできませんが、扱っている入力インスタンスのパラメーター値が小さいことがわかっている場合は、それを小さい数値に修正してアルゴリズムを使用できます。

フォーマルメソッドでは、これと同様のトリックを使用して、停止や同様の問題の決定不能性に対処します。しかし、決定したいことが複雑な場合、アルゴリズムの複雑さは、それらのインスタンスでアルゴリズムを実行するよりも良いとは考えられません。

他の質問に関して、入力を十分に制限すれば、停止の問題は簡単になります。たとえば、入力が多項式時間アルゴリズムであることがわかっている場合、それらの停止問題を決定するのは簡単です(すべての多項式時間アルゴリズムが停止するため)。

フォーマルメソッドで発生する問題は通常決定不能です。実際にこれらの問題をどのように扱うかについての文献を確認することをお勧めします。


4

正式に厳密な答えではありませんが、ここにそれがあります:

永久に停止するかループするかを決定する際の問題。一度に1つの要素または数の間隔で有限コレクションをループすることは問題ありません。編集:明らかに、これは、反復されているコレクションまたは間隔が、反復されている(または、少なくとも成長が禁止されている)ときに変更が禁止されている場合(不変性など)にのみ機能します。

最大のスタック深度を許可したり、各反復で負でないパラメーターが減少するように強制するなど、有限にする人工的なルールを設定しない限り、再帰はおそらく大丈夫ではありません。

任意のゴトは一般的に悪いです。後向きのゴトは、無限ループになる可能性が非常に高いです。

whilesおよびdo-whilesステートメントは、実行中に変更が保証されない、または保証されない条件に依存するため、問題です。それを制限する可能性のある(しかし、おそらく非常に不満足な)方法は、可能な最大の反復回数を与えることです。


2

スクリプト言語の定義、およびスクリプト作成者からの「期待」とはどういう意味ですか。

O(nω)

Aaron R. Bradley、Zohar Manna、およびHenny B. Sipmaによる多項式プログラムのクラスにも同様の結果があります。しかし、私の知る限り(ここでは間違っているかもしれません)、ランタイムは二重に指数関数的です(基本的には、グレブナー基底の計算に必要な時間です)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.