Алгоритм вирішення "проблеми зупинки" Тьюрінга


23

"Алан Тьюрінг довів у 1936 році, що загальний алгоритм вирішення проблеми зупинки для всіх можливих пар програм-введення не може існувати"

Чи можу я знайти загальний алгоритм для вирішення проблеми зупинки для деяких можливих пар введення програми?

Чи можу я знайти мову програмування (або мови), де я для будь-якого виду програми цією мовою може вирішити, чи припиняється програма чи запускається назавжди?


Аналогічне запитання: stackoverflow.com/questions/8412741/…

3
CACM мала дуже цікаву статтю у травні: Доведення програми припинення
Крістоф Валєш

3
"загальний алгоритм [...] для деяких можливих пар введення програми" - це близько до суперечливості. Гадаю, ви хочете обмежити себе нескінченним підкласом усіх програм?
Рафаель

Відповіді:


25

Чи можу я знайти загальний алгоритм для вирішення проблеми зупинки для деяких можливих пар введення програми?

Так, авжеж. Наприклад, ви можете написати алгоритм, який повертає "Так, він припиняється" для будь-якої програми, яка не містить ні циклів, ні рекурсії, і "Ні, вона не закінчується" для будь-якої програми, що містить while(true)цикл, який обов'язково буде досягнуто і не містить заява про перерву, і "Данно" для всього іншого.

Чи можу я знайти мову програмування (або мови), де я для будь-якого виду програми цією мовою може вирішити, чи припиняється програма чи запускається назавжди?

Ні, якщо ця мова є повною Тьюрінгом, ні.

Однак є цілі мови, які не є Тюрінгом, наприклад, Coq , Agda або Microsoft Dafny, для яких проблема зупинки вирішується (і насправді їх вирішують відповідні системи типів, що робить їх загальними мовами (тобто програма, яка може не припинятися, не буде скласти)).


1
Клас примітивно-рекурсивних функцій - це відома «мова програмування», для якої проблема зупинки тривіально вирішальна.
Рафаель

Існує декілька мов " повного функціонального програмування ", в яких всі програми досяжно закінчуються.
Андерсон Грін

3

Я думаю, що всі відповіді тут повністю і зовсім пропускають суть. Відповідь на питання: якщо припустити, що програма призначена для зупинки, то так, ви краще зможете показати її зупинки. Якщо ви не можете показати, що вона зупиняється легко, програму слід вважати дуже погано написаною та відхиленою Контролем якості як такою.

Насправді ви можете написати відповідний машинний алгоритм, залежить від мови введення програми та наскільки ви амбітні. Це розумна мета дизайну для мови програмування, що дозволяє легко довести припинення.

Якщо мова є C ++, ви, ймовірно, не можете написати інструмент, адже навряд чи ви коли-небудь запустили би парсер, не кажучи вже про те, що він підтвердить припинення. Для кращої структурованої мови ви повинні мати можливість створити доказ або принаймні зробити це з певними припущеннями: в останньому випадку інструмент повинен вивести ці припущення. Аналогічним підходом було б включення тверджень про закінчення в мові та використання їх у складних ситуаціях, коли інструмент буде довіряти твердженням.

Суть полягає в тому, що, здається, ніхто не розуміє, що перевірка припинення програми дійсно можлива, тому що (хороші) програмісти, які мають намір писати такі програми зупинки, завжди роблять це навмисно і з розумовою картиною того, чому вони припиняються та діють правильно: такий код навмисно написано так, зрозуміло, що вони зупиняються і є правильними, і якщо розумний алгоритм не може цього довести, можливо, з деякими підказками, програму слід відхилити.

Суть: програмісти не пишуть довільних програм, тому теза теореми зупинки не задоволена і висновок не застосовується.


4
Я думаю, що саме ви повністю і зовсім пропустили пункт. Перший абзац вашої відповіді не стосується питання, оскільки він запитує про алгоритми - а не про те, що людина може чи не може довести. Решта відповіді відповідає на перший абзац питання, тобто чи алгоритм може підтвердити припинення деяких програм. Усі попередні відповіді вже сказали «так» тому.
sepp2k

3
Ваше твердження про те, що можна написати алгоритм, який може підтвердити завершення кожної добре написаної програми достатньо простою мовою, повністю завершеною Тьюрінгом, є абсолютно помилковим. Для кожного можливого алгоритму, який намагається довести припинення, існують проблеми, коли кожна програма, яка вирішує цю проблему, не може бути доведена, щоб зупинити цей алгоритм. Тож якщо ви не скажете, що кожна програма, яка вирішує цю проблему, погано написана за визначенням (що було б смішно), що спростує вашу думку.
sepp2k

1
@Sam Якщо хтось запитає, чи зупиняється якийсь код, я перегляну його і спробую розібратися. Але я не алгоритм. І так, можна написати алгоритм, який може перевірити, чи зупиняється програма для багатьох програм. Але це не те, що сказав Іттрил. Yttrill сказав, що це можливо для всіх добре написаних програм. І як я вже говорив у своєму попередньому коментарі, це просто помилково, якщо ви не стверджуєте, що певні проблеми можна вирішити лише погано написаними програмами (що знову-таки було б смішним).
sepp2k

1
@Sam "мені здається, що програми, навмисно написані для зупинки, можна легко проаналізувати на зупинку умов" - якщо це було так, чому б у нас не було таких інструментів? Це не так, як якщо б люди не намагалися. (Один винуватець переважає метод: під час компіляції ви не знаєте всього коду, який буде виконуватися.)
Рафаель

1
@Sam "чи існує нескінченний цикл" - важко підійти навіть для циклу реального світу. Звичайно, мене вчили, як знайти петлю-інваріантів, але це не означає, що я можу знайти її (легко) у багатьох випадках. Наскільки я знаю, здогадка та доказ є золотим стандартом у наші дні. Знову ж , якщо були досить загальні алгоритми, я б очікувати , що вони будуть включені в основні компілює або Іди (які роблять виконати деякі тривіальні, синтаксичні перевірки). Чи можете ви дати посилання на досить сильний алгоритм?
Рафаель

3

відмінне і (навмисне глибоке) питання. дійсно існують програми зупинки виявлення, які можуть досягти успіху на обмежених наборах входів. її активна область досліджень. він має дуже міцні зв'язки з (автоматизованими) областями доведення теореми.

однак, схоже, що в інформатиці немає точного терміна для "програм", які "іноді" досягають успіху. слово "алгоритм" зазвичай зарезервоване для програм, які завжди зупиняються.

ця концепція, як видається, відрізняється від імовірнісних алгоритмів, де теоретики CS наполягають на тому, що існує певна відома або обчислювана ймовірність їх успіху.

є термін напівалгоритми, який використовується іноді, але, мабуть, це синонім рекурсивно перелічуваних чи не обчислюваних.

тому для цілей тут назвіть їх квазіалгоритмами . Концепція відрізняється від розв'язувальної проти невизначеної.

AXBYXYXYBA

в CS ця «квазі алгоритм ієрархія», здається, вивчається здебільшого лише неофіційно.

це виявляється в дослідженнях зайнятих бобрами [1] та проблемі PCP [2]. насправді обчислювальна атака на основі ДНК на PCP може розглядатися як квазіалгоритм. [3] і це спостерігається в інших сферах, що вже відзначалися, наприклад, доведення теореми [4].

[1] Новий напад тисячоліття на проблему зайнятого бобра

[2] Вирішення проблеми листування постів Чжао (v2?)

[3] Використання ДНК для вирішення обмеженої проблеми кореспонденції Карі та ін

[4] підтвердження припинення програми Cook і співавт., Comm. ОСББ

(тож це насправді дуже глибоке запитання, яке заслуговує на те, що defn заслуговує на TCS.SE imho ... можливо, хтось може перепросити його там таким чином, щоб він підходив і залишався)


ps як вражаючий приклад того, наскільки потужними можуть бути квазіалгоритми, ACM зазначає, що функція Ackermanns може бути доведена до зупинки квазіалгоритмом, але вона більша, ніж (не обчислюється) усіх примітивних рекурсивних функцій.
vzn

1
"слово" алгоритм "зазвичай зарезервоване для програм, які завжди зупиняються." - Я не впевнений, що це правда. Навколо існує багато алгоритмів, що частково закінчуються (особливо в верифікації), і я ніколи не чув, щоб хтось не сказав "алгоритм".
Рафаель

є неофіційні використання "алгоритму". "частково закінчується" нормально, але проблематично nonstd. як зазначено, поки що, схоже, не існує строго вираженого терміну. Вікіпедія визначає алгоритм як ефективний метод, тобто вирішуваний з наступними характеристиками (1) завжди дає певну відповідь, а не коли-небудь дає відповідь; (2) завжди давати правильну відповідь і ніколи не давати неправильну відповідь; (3) завжди виконуватись у кінцевій кількості кроків, а не у нескінченному числі; (4) робота для всіх випадків проблем класу.
vzn

а потім у цій же статті сказано: «Подальше з'ясування терміна" ефективний метод "може включати вимогу, що при виникненні проблеми поза класом, для якого метод ефективний, метод може зупинятись або циклічати назавжди без зупинки , але не повинен повертати результат, як ніби це відповідь на проблему ". тобто це майже суперечить собі!?! настільки чітко, чудово, що в ключовому питанні існує певна плутанина, і існуюча термінологія не є суворою. зауважте, що слово "алгоритм" наближається до більш ніж тисячоліть і так значно змістилося ....
vzn

Це правда: традиційне значення, мабуть, є «ефективним методом» у тому, як говорить Вікіпедія (немає жодних суперечностей у реченні, яке ви цитуєте; хоча це трохи незрозуміло) - люди не уявляли функцій / алгоритмів, які не припинялися (для деякі входи). Я думаю, що це змінилося з 1950-х років; як я вже говорив, сьогодні люди чітко називають частково закінчуючий метод «алгоритмом».
Рафаель

2

Поки мова, про яку йде мова, є достатньо складною (тобто, якщо вона є Тюрінгом завершеною), то завжди існують програми на тій мові, які жодна програма не може довести її до завершення.

Оскільки всі, крім найпримітивніших мов, є Тьюрінгом завершеними (потрібно лише щось на зразок змінних та умовних умов), ви могли б створити лише дуже маленькі мови іграшок, для яких ви могли б вирішити проблему зупинки.

Редагувати: З огляду на коментарі, дозвольте мені бути більш чіткими: будь-яка мова, яку ви могли б розробити, для якої ви могли б вирішити проблему зупинки, обов'язково повинна бути неповною. Це виключає будь-яку мову, що містить відповідний набір основних інгредієнтів (наприклад, "змінні, умовні умови та стрибки", або як каже @ sepp2k, загальне "поки" -loop).

Мабуть, існує кілька практичних "простих" мов, таких як (наприклад, розв'язувачі теорем, такі як Coq і Agda). Якщо вони задовольняють ваше уявлення про "мову програмування", ви можете дослідити, чи задовольняють вони якусь повноту, чи вирішує для них проблема зупинки.


3
"Оскільки всі, крім найпримітивніших, мов Тюрінг завершені (потрібно лише щось на зразок змінних та умовних умов)" Це неправда. Перш за все, вам, як мінімум, знадобиться рекурсія або якась форма циклічної конструкції (яка повинна бути такою ж потужною, як цикл у той час - простого циклу підрахунку недостатньо). По-друге, я не думаю, що є багато людей, які називали б такі мови, як Coq або Agda (які є загальними і, таким чином, не складають повноцінних) примітивними або іграшковими мовами.
sepp2k

@ sepp2k: Ну так. Арифметика з піано також досить корисна і не є Тюрінг повною. Я думаю, спрощене твердження. Якщо ОП достатньо знайома з проблемою, вона, сподіваємось, зможе заповнити технічні деталі.

3
Існує величезна прірва між тим, що бути "достатньо складним" і бути повною Тьюрінгом. Кок справді складний, і він підходить для дуже широкого кола практичних завдань.

1
@ Kerrek SB Добре можливо, що мова повного Тьюрінга використовується способами, які залишаються доступними до припинення. Якщо ви можете довести, що рекурсивна формула завжди наближається до її закінчувального стану (як факторна функція), ви можете довести, що вона припиняється, хоча ви не зможете обробляти кожен тип рекурсії.

@ArtB: Звичайно, завжди є деякі програми, які можуть бути доведені до припинення. Перше питання ОП може натякнути на це, хоча я не впевнений, що дотримуюся його повністю. Наприклад, у вас не міг бути "загальний алгоритм", який визначає, чи припиняється будь-яке сімейство програм, тоді як, навпаки, ви могли б побудувати обмежене сімейство функцій таким чином, що припускаючи, що функція належить до цієї сім'ї, ви можете алгоритмічно сказати, чи це припиняється. (Я не впевнений, чи може ця родина нетривіальна. Я думаю, що може, але я не можу зробити приклад.)

2

TT

Це досить банально. Якщо ми візьмемо об'єднання будь-якого підмножини зупиняючих ТМ і будь-якого підмножини неприпиняючих ТМ, то в результаті буде встановлено ТМ, для яких проблема зупинки вирішується (запустіть обидві машини паралельно, якщо перша приймає TM зупинки, якщо другий приймає, то машина не зупиняється). Однак це не призведе до дуже цікавих мов.

ALogTimecM


1

Так, можна, але я сумніваюся, що це стане в нагоді. Вам, мабуть, доведеться зробити аналіз справи, і тоді ви зможете шукати лише найбільш очевидні випадки. Наприклад, ви можете отримати файл для коду while(true){}. Якщо файл має цей код, він ніколи не закінчується ^. Більш загально, ви можете сказати, що програма без циклу чи рекурсії завжди припиняється, і ви можете зробити декілька випадків, які могли б гарантувати, що програма припиниться чи не буде, але навіть для програми середнього розміру це буде дуже складно і у багатьох випадках не вдасться дати вам відповідь.

tl; dr: Так, але ви не зможете зробити це корисним для більшості корисних програм.


^ Так, технічно, якщо цей код відсутній на шляху коду або є інші потоки, він все-таки може припинятися, але я зазначаю тут загальний пункт.


4
Чому, на вашу думку, Кок і Агда не корисні? Ви завищуєте цінність Тюрінга-повноти.

Я використовував Coq, але моя заява залишається, оскільки більшість комерційних програм написані на Java / C ++ / Ruby / C #, щодо яких мої претензії є правдивими. Такі програми, якими 90% людей зацікавлені у написанні, не принесуть користі. В основному, якщо ви не знаєте про Coq / Agda тощо, ви не є цільовим ринком для цього.

5
Я б сказав, що 99% програм у реальному світі отримали б користь від того, щоб реалізовуватись у неповноцінному підмножині мови. Ви не будете реалізовувати, скажімо, функцію Ackermann щодня. 100% CRUD не потребує "реальної" мови. Обробка даних майже завжди банальна. Дивіться проект Terminator - вони навіть обслуговують гідну підмножину можливих програм C ++, що більш ніж достатньо для реальних речей (включаючи драйвери та інший код низького рівня).

Більшість проектів у реальному світі хочуть повторно використовувати бібліотеки, написані на мовах, повних Turing, та використовувати їх IDE та налагоджувачі та навчальні посібники. Так, ви можете робити речі на нетурбінських мовах, але я не можу уявити, щоб деякі насправді говорили "Я хочу зробити X", а моя відповідь - "Використовувати Coq". ps- дякую за те, що ви познайомили мене з проектом «Термінатор» .

4
незрозуміло величезна частка ділової логіки реалізована вже в не завершеному Тьюрінгом SQL. І DSL, і eDSL зараз зростають. Так, незабаром більшість програмістів бізнес-програм забудуть про всі мови загального призначення.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.