チューリング完全性にはdo-whileループで十分ですか?


22

命令型プログラミング言語では、言語をチューリング完全にするための制御フロー構造としてwhile-doループで十分であることを知っています(制御フローに関する限り-もちろん、無制限のメモリと特定の演算子も必要です...) 。私の質問の要点は、do-whileループはwhile-doループと同じ計算能力を持っていますか?言い換えれば、命令を完全にスキップすることが不可能な場合、言語をチューリング完全にすることができます。

ここでのセマンティクスの一部は少し曖昧かもしれないことを理解しているので、具体的な例で実際の質問を言いましょう。

Brainfuck(BF)は、Turingターピットであり、唯一の制御フローはwhile-doループです[...](Brainfuckに慣れていない場合に備えて、質問の下部に完全な言語仕様があります)。さんはどこ、*新しい言語BFを定義してみましょう,.+-<>BFと同じ意味を持っていますが、代わりに[]私たちが持ってい{}たdo-whileループを示しています。つまり、BFとの唯一の違いは、すべてのループが少なくとも1回実行されてから、さらに反復がスキップされることです。

BF *チューリング完全ですか?もしそうなら、BFをBF *に変換する方法に興味があります。そうでない場合、どうすればそれを証明できますか?

私自身のいくつかの観察:

  • すべてのBFプログラムをBF *に翻訳できるわけではありません。たとえば、BF *で値を読み取ったり印刷したりするプログラムを書くことは不可能です。プログラムが1つ以上の値を印刷する可能性がある場合、常に少なくとも1つを印刷します。ただし、BF *に変換できるBFのチューリング完全サブセットがある場合があります。
  • [f](最初の反復の効果をキャンセルしようとして)に(最初の反復の効果をキャンセルするために)単純に変換することはできません(a fのみで構成されるBrainfuckプログラム)。すべての計算可能な関数に計算可能な逆関数とb)がある場合でも、ループが必ずしも少ないとは限らないため、このステップを再帰的に適用しても、最初に終了することは保証されません。+-[]<>f-1{f}f-1f

Brainfuck言語の簡単な概要を次に示します。Brainfuckは、各セルに最初はゼロのバイト値が含まれる無限テープで動作します。オーバーフローはラップアラウンドするため、255をインクリメントすると0になり、逆も同様です。言語は8つの命令で構成されています。

+   Increment the current cell.
-   Decrement the current cell.
>   Move tape head to the right.
<   Move tape head to the left.
,   Input a character from STDIN into the current cell.
.   Output the current cell as a character to STDOUT.
[   If the current cell is zero, jump past the matching ].
]   If the current cell is non-zero, jump back to just behind the matching [.


興味深いが、それは完全に慎重に構築されていないと思います。[]BFで「while do」ループを正確に定義していません。表のように、左右の括弧は現在のセルのゼロ/非ゼロを評価します。それで、対応する{}ブレース評価ロジックの正確な説明は何ですか?Computer Science Chatでさらにダイアログ/ディスカッションを提案します。また、あなたの「観察」は、証拠のない「仮定」または「命題」に似ています。
vzn

@vznこれらは良い点です。私はの明らかな定義は何もしないことと同じである{}と考えた。今後数日間はあまり時間がありませんが、時間ができたらチャットに参加します。{}]
マーティンエンダー

残念ながら、これは明らかにやや微妙で、ここには2つのまったく異なる質問があるようです。(1)while-doループ(および「その他」)を備えたチューリング完全言語を指定すると、代わりにdo-whileループのみを備えたチューリング完全言語に変換できます。しかし、答えるには、「その他のもの」について詳しく知る必要があります。(2)与えられたBFと、与えられた定義を{}持ち、取り去る新しいBF * []は、BF *チューリング完全です。BF []は、チューリング完全言語のwhile-doループに似た/類似しものにすぎないという理解で。
vzn

1
@vznパート(1)は私の質問のTL; DRパートのみでした。これはおそらく「ある言語」で答えることは不可能であることを十分に承知しています。私は本当に非常にシンプルなおもちゃの言語(BF)の観点から、実際の質問を言葉で表現私は考え出したので(ループの振る舞いにそれを絞り込むきた理由はここにある場合 BF *は、それを簡単にするだろうとTCをであることを示すことができますdo-whileループのみを持つ他の言語で表示するため)。しかし、BFループが他の言語のwhile-doループとどのように異なると思うかはわかりません。
マーティンエンダー

回答:


10

私はBrainfuckを知らないので、あなたは私の擬似コードからいくつかの翻訳をしなければならないでしょう。しかし、Brainfuckが賢明に動作すると仮定すると(ha!)、以下のすべてが適用されます。

do-whileはwhile-doと同等です。 do X while Yはに相当しX; while Y do X、条件式while Y do Xがあると仮定するとに相当しif Y then (do X while Y)ます。

条件がなければ人生は少し難しくなります。while-doがある場合は、次のif Y then Xようなものを使用してシミュレートできます。

B := true
while (Y and B) do
    X
    B := false
endwhile

しかし、do-whileしかなかったらどうしますか?私は、変数の現在の値が与えられif Y then XX終了すると仮定して、以下がシミュレートすると主張しています。(これは保証されていません。プログラムは、変数の値をループしても、if y=0 then loopforeverifを終了します)。ましょう、...、で修正変数であるとしましょうこと、それが使用するように改変する代わりにこれらの変数のそれぞれについて。変数とを交換する明らかなコードを示します。y != 0XV1VnXX'XVi'Viswap(A,B)AB

V1' := V1; ...; Vn' := Vn
V1'' := V1; ...; Vn'' := Vn
C := 0
do
    X'
    swap (V1',V1''); ...; swap (Vn',Vn'')
    C := C+1
while Y and C<2
V1 := V1'; ...; Vn := Vn'

アイデアは次のとおりです。まず、それYが偽であると仮定します。X一度行うことをシミュレートし、結果をV1''、...、Vn'';に保存します。V1'、...、Vn'の元の値を保持しますV1、...、Vn。次に、を割り当てますがV1 := V1'; ...; Vn := Vn'、これは何も行いません。したがって、Yがfalseの場合、何もしていません。今、それYが本当だと仮定します。ここでX 2回シミュレート、「primed」変数と「double-primed」変数の両方に結果を保存します。したがって、ループの最後の割り当てには、X一度計算された効果があります。Y「プライミングされていない」変数にのみ依存するため、その値はループを繰り返し実行しても影響を受けないことに注意してください。

ではX、変数の現在の値で終了しない場合はどうでしょうか?(この可能性を指摘してくれたMartin Enderに感謝します。)その場合、X上記と同様のアイデアを使用して、命令ごとにシミュレートする必要があります。各命令は完全に終了するため、if上記のシミュレーションを使用して、「オペコードがfooの場合、これを実行し、バーの場合、それを実行し、...」の行に沿って命令のデコードを実行できます。そのため、次に、ループを使用しての命令を反復処理Xし、命令ポインターなどを使用して、次に実行する命令を認識します。ループの各反復の終わりに、まだ停止しているYかどうかを確認しXます。場合はYfalseで、交換技術はの効果を元に戻すために私たちをことができますXの最初の命令。


1
これはきちんとした考えですが、私はここに1つの問題があると思う:場合考えるYfalseですが、X変数値の現在のセットに終了しませんが。if Y then X常に終了する必要があるため、翻訳は終了しませんX'
マーティンエンダー

1
@MartinBüttnerウル あなたが正しい。そのため、ループを使用してX命令Yごとにシミュレートし、各命令の後にチェックする必要があります。各命令は終了することが保証されているため、すべてが機能します。しかし、書き留めるのは苦痛です。
デビッドリチャービー

1
Xwhileループ/条件付きで始まる場合、そのように分解できるかどうかは完全にはわかりません。これについてもう少し考えなければなりません。
マーティンエンダー

また、「今、ループを使用して、Xの命令を反復処理し、命令ポインターなどを使用して、次に実行する命令を確認します。」私はこれ自体が何らかの条件を必要とするかもしれないと感じています。
マーティンエンダー

1
X'非線形である場合に「各命令」をどのように定義するかはまだ完全にはわかりません。シンプルだが自明ではないおもちゃの詳細を追加していただけますXか?例えばdo (while A do B) while C?(アウターdo whileは、while do現在翻訳中のアウターから来ています)
マーティンエンダー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.