Celem tego wyzwania jest (ostatecznie) wygenerowanie każdego możliwego programu zatrzymania w wybranym języku. Na początku może się to wydawać niemożliwe, ale możesz to zrobić, bardzo ostrożnie wybierając kolejność wykonywania.
Poniżej znajduje się schemat ASCII ilustrujący to. Niech kolumny reprezentują numerację każdego możliwego programu (każdy program jest skończoną liczbą symboli ze skończonego alfabetu). Niech każdy wiersz reprezentuje pojedynczy krok w wykonaniu tego programu. X
Stanowią wykonanie wykonaniu tego programu w tym czasie kroku.
step# p1 p2 p3 p4 p5 p6
1 X X X X X X
2 X X X X X
3 X X X X
4 X X X X
5 X X X
6 X X
7 X X
8 X X
9 X X
∞ X X
Jak widać, programy 2 i 4 się nie zatrzymują. Jeśli miałbyś je wykonać pojedynczo, twój kontroler utknąłby w nieskończonej pętli, którą jest program 2 i nigdy nie wyprowadzałby programów 3 i późniejszych.
Zamiast tego stosujesz podejście typu „ jaskółczy ogon” . Litery przedstawiają możliwą kolejność wykonania dla pierwszych 26 kroków. Są *
to miejsca, w których program został zatrzymany i jest generowany. Są .
to kroki, które nie zostały jeszcze wykonane.
step# p1 p2 p3 p4 p5 p6
1 A C F J N R V
2 B E I M Q * Z
3 D H * P U
4 G L T Y
5 K O X
6 * S .
7 W .
8 . .
9 . .
∞ . .
Wymagania dotyczące języka docelowego
Język docelowy (ten interpretowany równolegle) musi być kompletny w Turingu. Poza tym może to być dowolny język, który jest kompletny z Turinga, w tym kompletne podzbiory Turinga dla znacznie większych języków. Możesz także dowolnie interpretować takie zasady, jak reguły systemu tagów cyklicznych. Możesz także utworzyć język do testowania, o ile możesz pokazać, dlaczego jest on kompletny w Turingu.
Na przykład, jeśli zdecydujesz się na test pieprzenia mózgu, najlepiej przetestować tylko []-+<>
podzbiór, ponieważ dane wejściowe nie są obsługiwane, a dane wyjściowe są po prostu wyrzucane (patrz poniżej).
Jeśli chodzi o program „kontrolera” (w który grasz), nie ma specjalnych wymagań. Obowiązują normalne ograniczenia językowe.
Jak stworzyć nieskończoną listę programów
Większość języków programowania może być reprezentowana jako seria symboli ze skończonego alfabetu. W takim przypadku stosunkowo łatwo jest wymienić listę każdego możliwego programu w kolejności rosnącej długości. Używany alfabet powinien być reprezentatywny dla wymagań języka docelowego. W większości przypadków jest to drukowany kod ASCII. Jeśli twój język obsługuje Unicode jako dodatkową funkcję, nie powinieneś testować każdej możliwej kombinacji znaków Unicode, tylko ASCII. Jeśli używasz tylko Twojego języka []-+<>
, nie testuj różnych kombinacji „komentujących” znaków ASCII. Języki takie jak APL miałyby własne specjalne alfabety.
Jeśli Twój język najlepiej jest opisać w jakiś sposób niealfabetyczny, np. Fractran lub Turing Machines, istnieją inne równie poprawne metody generowania listy wszystkich możliwych prawidłowych programów.
Interpretacja stale rosnącej listy programów
Kluczową częścią tego wyzwania jest napisanie równoległego interpretera dla rosnącej listy programów. Oto kilka podstawowych kroków:
- Dodaj skończoną liczbę programów do listy
- Interpretuj każdy program na liście indywidualnie przez określony czas. Można to osiągnąć, wykonując jeden krok instrukcji dla każdego. Zapisz wszystkie stany.
- Usuń wszystkie programy kończące / zgłaszające błędy z listy
- Wyjście czysto zatrzymanych * programów
- Dodaj więcej programów do listy
- Symuluj kolejno każdy program, pobierając wykonanie starszych programów tam, gdzie je przerwał
- Usuń wszystkie programy kończące / zgłaszające błędy z listy
- Wyjście czysto zatrzymanych * programów
- powtarzać
* Powinieneś wypisywać tylko programy, które zatrzymują się w sposób czysty. Oznacza to, że podczas wykonywania nie zgłoszono żadnych błędów składniowych ani nieprzechwyconych wyjątków. Programy, które proszą o wejście, również powinny zostać zakończone bez ich wysyłania. Jeśli program produkuje dane wyjściowe, nie powinieneś ich kończyć, po prostu wyrzuć dane wyjściowe.
Więcej zasad
- Nie wolno odradzać nowych wątków zawierających testowane programy, ponieważ odciąża to pracę równoległą do systemu operacyjnego hosta / innego oprogramowania.
- Edycja: Aby zamknąć potencjalne przyszłe luki, nie możesz
eval
(ani żadnej pokrewnej funkcji) części kodu testowanego programu. Państwo możeeval
bloku kodu z kodem tłumacza. (Odpowiedź BF-in-Python jest nadal ważna zgodnie z tymi zasadami). - To jest golf golfowy
- Język, w którym piszesz zgłoszenie , nie musi być taki sam, jak język, w którym testujesz / publikujesz.
- Należy założyć, że dostępna pamięć jest nieograniczona.
- Udowadniając kompletność Turinga, możesz założyć, że dane wejściowe są zakodowane na stałe w programie, a dane wyjściowe można odczytać ze stanu wewnętrznego programu.
- Jeśli twój program sam się wypisuje, prawdopodobnie jest to błąd lub poliglota.
"If your program outputs itself, it is probably wrong or a polyglot."