Wiem, że w imperatywnych językach programowania pętla while-do jest wystarczająca jako konstrukcja przepływu sterowania, aby uzupełnić język Turinga (jeśli chodzi o przepływ sterowania - oczywiście potrzebujemy również nieograniczonej pamięci i niektórych operatorów ...) . Istota mojego pytania brzmi: czy pętla „do-while” ma taką samą moc obliczeniową jak pętla „do-do”? Innymi słowy, czy język może być kompletny przez Turinga, jeśli nie można całkowicie pominąć instrukcji.
Zdaję sobie sprawę, że niektóre semantyki mogą być nieco niejednoznaczne, więc pozwólcie, że sformułuję rzeczywiste pytanie konkretnym przykładem:
Brainfuck (BF) to tarpit Turinga, w którym jedynym przepływem kontrolnym jest pętla while-do, oznaczona jako [...]
(na dole pytania znajduje się pełna specyfikacja języka, na wypadek, gdyby nie znasz Brainfuck). Zdefiniujmy nowy język BF *, w którym ,.+-<>
ma taką samą semantykę jak w BF, ale zamiast tego []
mamy {}
co oznacza pętlę „do-while”. Oznacza to, że jedyną różnicą w stosunku do BF jest to, że każda pętla jest wykonywana co najmniej raz, zanim możliwe będzie pominięcie kolejnych iteracji.
Czy BF * Turing jest kompletny? Jeśli tak, byłbym zainteresowany tym, jak mógłbym przetłumaczyć BF na BF *. Jeśli nie, to jak to udowodnić?
Kilka moich własnych obserwacji:
- Nie każdy program BF można przetłumaczyć na BF *. Na przykład niemożliwe jest napisanie programu w BF *, który może, ale nie musi, odczytać lub wydrukować wartość - jeśli program potencjalnie wydrukuje jedną lub więcej wartości, zawsze wydrukuje przynajmniej jedną. Jednak może istnieć kompletny podzbiór BF Turinga, który można przetłumaczyć na BF *.
- Nie możemy po prostu tłumaczyć
[f]
(gdzief
jest jakiś arbitralny program składający się tylko z Brainfuck+-[]<>
) na (w celu anulowania efektu pierwszej iteracji), ponieważ a) nie każda funkcja obliczalna ma obliczalną odwrotność i b) nawet jeśli tak, niekoniecznie miałoby mniej pętli niż dlatego rekursywne wykonanie tego kroku nie gwarantuje zakończenia.f-1{f}
f-1
f
Oto krótki przegląd języka Brainfuck. Brainfuck działa na nieskończonej taśmie, w której każda komórka zawiera wartości bajtów, początkowo zerowe. Przepełnienia się zawijają, więc zwiększenie 255 daje 0 i odwrotnie. Język składa się z 8 instrukcji:
+ 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 [.
[]
nie definiuje dokładnie pętli „while do” w BF. tak jak w tabeli, lewy i prawy nawias oceniają bieżącą komórkę zero / zero. więc jaki jest dokładny opis odpowiedniej {}
logiki oceny nawiasów klamrowych? zaproponuj dalsze dialogi / dyskusje na czacie informatyki . również „obserwacje” bardziej przypominają „postulaty” lub „twierdzenia” bez dowodu.
{}
byłoby {
nic nie robić i }
to samo co ]
. W ciągu najbliższych kilku dni nie będę miał dużo czasu, ale dołączę do ciebie na czacie, kiedy znajdę trochę czasu.
{}
i odebraniem []
, BF * Turing jest kompletny. ze zrozumieniem, że BF []
jest konstrukcją tylko czymś podobnym / analogicznym do pętli while-do w kompletnych językach Turinga.