Участник:Shersh/Теорема о рекурсии — различия между версиями
Shersh (обсуждение | вклад) (теорема о неподвижной точке) |
(→Пример использования) |
||
(не показано 15 промежуточных версий 4 участников) | |||
Строка 1: | Строка 1: | ||
+ | По [[Теорема о рекурсии | теореме о рекурсии]], программа может знать свой исходный код. Значит, в неё можно написать функцию <tex> \mathrm{getSrc()} </tex>, которая вернёт строку {{---}} исходный код программы. Далее будем считать, что такая функция определена в каждой программе. | ||
== Неразрешимость универсального языка == | == Неразрешимость универсального языка == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{Утверждение | {{Утверждение | ||
|id=proposalU. | |id=proposalU. | ||
− | |statement=Универсальный язык неразрешим | + | |statement=[[Разрешимые (рекурсивные) языки#Пример неразрешимого множества | Универсальный язык]] неразрешим |
|proof= | |proof= | ||
− | + | Допустим, что он разрешим. Тогда напишем такую программу: | |
<code> | <code> | ||
p(x): | p(x): | ||
− | '''if''' u( | + | '''if''' u(getSrc(), x) |
− | ''' | + | '''while''' ''true'' |
'''else''' | '''else''' | ||
'''return''' 1 | '''return''' 1 | ||
</code> | </code> | ||
− | Если <tex> u(p, x) = 1 </tex>, тогда программа <tex> p </tex> на входе <tex> x </tex> | + | Если <tex> u(p, x) = 1 </tex>, тогда программа <tex> p </tex> на входе <tex> x </tex> должна вернуть <tex> 1 </tex>, но по условию <tex> if </tex> она зависает, а следовательно, не принадлежит универсальному языку. |
− | Если же <tex> u(p, x) | + | Если же <tex> u(p, x) \neq 1 </tex>, то мы пойдём во вторую ветку условного оператора и вернём <tex> 1 </tex>, значит, пара <tex> |
+ | \langle p, x \rangle </tex> принадлежит универсальному языку, но <tex> u(p, x) \neq 1 </tex>, значит, пара не принадлежит. Опять получили противоречие. | ||
}} | }} | ||
+ | |||
== Теорема Успенского-Райса == | == Теорема Успенского-Райса == | ||
<tex> A </tex> {{---}} разрешимое семейство языков. | <tex> A </tex> {{---}} разрешимое семейство языков. | ||
− | <tex> L_A </tex> {{---}} | + | <tex> L_A </tex> {{---}} множество программ, удовлетворяющих св-ву <tex> A </tex>. |
+ | |||
+ | Теперь допустим, что язык <tex> L_A </tex> разрешим. Тогда напишем такую программу: | ||
<code> | <code> | ||
+ | propA(code): | ||
+ | // программа, разрешающее свойство языка <tex> A </tex> | ||
+ | f(x): | ||
+ | // такая программа <tex> f </tex>, что <tex>f \in A </tex>; существует потому что <tex> A </tex> {{---}} нетривиальное свойство | ||
+ | g(x): | ||
+ | // такая программа <tex> g </tex>, что <tex>g \notin A </tex>; существует потому что <tex> A </tex> {{---}} нетривиальное свойство | ||
p(x): | p(x): | ||
− | '''if''' | + | '''if''' propA(getSrc()) |
− | + | '''return''' g(x) | |
'''else''' | '''else''' | ||
− | + | '''return''' f(x) | |
</code> | </code> | ||
+ | |||
+ | Если <tex> p </tex> не удовлетворяет свойству <tex> A </tex>, тогда будет выполняться всегда вторая ветка, и <tex> L(p) = L(f) </tex>. Но язык программы <tex> f </tex> принадлежит <tex> A </tex>. Получили противоречие. | ||
+ | |||
+ | Если <tex> p </tex> удовлетворяет свойству <tex> A </tex>, то <tex> L(p) = L(g) </tex>, а <tex> g \notin A </tex>. Опять получили противоречие. | ||
== Колмогоровская сложность == | == Колмогоровская сложность == | ||
{{Определение | {{Определение | ||
Строка 40: | Строка 49: | ||
|definition='''Колмогоровской сложностью''' строки <tex> x </tex> называется функция <tex> K(x) </tex>, которая равна минимальной длине программы <tex> p : p(\varepsilon) = x </tex>. | |definition='''Колмогоровской сложностью''' строки <tex> x </tex> называется функция <tex> K(x) </tex>, которая равна минимальной длине программы <tex> p : p(\varepsilon) = x </tex>. | ||
}} | }} | ||
+ | Сложность считается в каком-то фиксированном языке программирования. Так, например, у языков C++ и Python будет разная колмогоровская сложность одной программы. | ||
+ | |||
=== Пример === | === Пример === | ||
− | Колмогоровская сложность программы, выводящей <tex> n </tex> нулей <tex> K(0^n) \leqslant | + | Колмогоровская сложность программы, выводящей <tex> n </tex> нулей <tex> K(0^n) \leqslant n + c </tex>. Просто программа, в которой записано <tex> n </tex> нулей. Но можно записать и более короткую программу для больших <tex> n </tex> со сложностью <tex> K(0^n) \leqslant \log{n} + c </tex>, например вот такую: |
<code> | <code> | ||
<tex>p_n</tex>(): | <tex>p_n</tex>(): | ||
Строка 66: | Строка 77: | ||
Начиная с <tex> x_0 </tex>, <tex> f(x) > |p| </tex>. | Начиная с <tex> x_0 </tex>, <tex> f(x) > |p| </tex>. | ||
}} | }} | ||
+ | |||
== Busy beaver == | == Busy beaver == | ||
+ | {{Утверждение | ||
+ | |id=proposalU. | ||
+ | |statement=Функция [[Busy beaver]] невычислима. | ||
+ | |proof= Предположим, что это не так. Тогда напишем такую программу | ||
+ | <code> | ||
+ | p(): | ||
+ | '''for''' i = 1..BB(<tex>|\mathrm{getSrc()}|</tex>) + 1 | ||
+ | do smth | ||
+ | </code> | ||
+ | |||
+ | Такая программа всегда совершает больше шагов, чем функция <tex> BB </tex> от этой программы. А это невозможно, так <tex> BB(|p|) </tex> равна максимальному числу шагов как раз этой программы. Получили противоречие. | ||
+ | }} | ||
+ | |||
== Аналог I теоремы Гёделя о неполноте == | == Аналог I теоремы Гёделя о неполноте == | ||
{{Теорема | {{Теорема | ||
Строка 72: | Строка 97: | ||
|statement = В любой "достаточно богатой системе" существует истинное недоказуемое утверждение. | |statement = В любой "достаточно богатой системе" существует истинное недоказуемое утверждение. | ||
|proof = | |proof = | ||
+ | Поясним, что это значит. Так как любой язык программирования эквивалентен [[Машина Тьюринга | машине Тьюринга]], то всё связанное с ним кодируется в [[Теории первого порядка | логике первого порядка]] с [[Классы_чисел#Аксиомы_Пеано | аксиомами Пеано]] (для этого достаточно, чтобы программа умела прибавлять к числу единицу и вызывать подпрограммы), поэтому можно в терминах программ получать утверждения, эквивалентные тем, что строил Гёдель. | ||
+ | |||
Можно переформулировать теорему следующим образом: невозможно доказать, что <tex> p(x) = \perp </tex>. | Можно переформулировать теорему следующим образом: невозможно доказать, что <tex> p(x) = \perp </tex>. | ||
− | + | Таким образом напишем такую программу: | |
<code> | <code> | ||
p(x): | p(x): | ||
Строка 82: | Строка 109: | ||
</code> | </code> | ||
}} | }} | ||
− | + | ||
== Теорема о неподвижной точке == | == Теорема о неподвижной точке == | ||
− | Зафиксируем главную нумерацию <tex> W </tex>. Обозначим за <tex> W_n </tex> множество слов, допускаемых программой с номером <tex> n </tex>. | + | Зафиксируем [[Главные нумерации | главную нумерацию]] <tex> W </tex>. Обозначим за <tex> W_n </tex> множество слов, допускаемых программой с номером <tex> n </tex>. |
{{Утверждение | {{Утверждение | ||
|id=идентификатор (необязательно), пример: proposalF. | |id=идентификатор (необязательно), пример: proposalF. | ||
Строка 92: | Строка 119: | ||
<code> | <code> | ||
p(q): | p(q): | ||
− | '''if''' p == q | + | '''if''' p.getSrc() == q.getSrc() |
− | + | '''return''' 1 | |
'''else''' | '''else''' | ||
'''while''' ''true'' | '''while''' ''true'' | ||
Строка 99: | Строка 126: | ||
Программа <tex> p </tex> знает свой код, что то же самое, что и знает свой номер. Как видно из её кода, она допускает только одно число {{---}} свой номер. | Программа <tex> p </tex> знает свой код, что то же самое, что и знает свой номер. Как видно из её кода, она допускает только одно число {{---}} свой номер. | ||
}} | }} | ||
+ | |||
+ | == Ссылки == | ||
+ | * [[wikipedia:Kolmogorov_complexity | Wikipedia {{---}} Kolmogorov_complexity]] | ||
+ | * [http://people.cs.uchicago.edu/~fortnow/papers/kaikoura.pdf Kolmogorov Complexity] | ||
+ | * [http://www.lektorium.tv/lecture/?id=13494 Дмитрий Ицыксон {{---}} Вычислимость и логика, Колмогоровская сложность] | ||
+ | |||
+ | [[Категория: Теория формальных языков]] |
Текущая версия на 23:56, 2 января 2017
По теореме о рекурсии, программа может знать свой исходный код. Значит, в неё можно написать функцию , которая вернёт строку — исходный код программы. Далее будем считать, что такая функция определена в каждой программе.
Содержание
Неразрешимость универсального языка
Утверждение: |
Универсальный язык неразрешим |
Допустим, что он разрешим. Тогда напишем такую программу:
p(x): if u(getSrc(), x) while true else return 1
Если Если же , тогда программа на входе должна вернуть , но по условию она зависает, а следовательно, не принадлежит универсальному языку. , то мы пойдём во вторую ветку условного оператора и вернём , значит, пара принадлежит универсальному языку, но , значит, пара не принадлежит. Опять получили противоречие. |
Теорема Успенского-Райса
— разрешимое семейство языков.
— множество программ, удовлетворяющих св-ву .
Теперь допустим, что язык
разрешим. Тогда напишем такую программу:
propA(code): // программа, разрешающее свойство языкаf(x): // такая программа , что ; существует потому что — нетривиальное свойство g(x): // такая программа , что ; существует потому что — нетривиальное свойство p(x): if propA(getSrc()) return g(x) else return f(x)
Если
не удовлетворяет свойству , тогда будет выполняться всегда вторая ветка, и . Но язык программы принадлежит . Получили противоречие.Если
удовлетворяет свойству , то , а . Опять получили противоречие.Колмогоровская сложность
Определение: |
Колмогоровской сложностью строки | называется функция , которая равна минимальной длине программы .
Сложность считается в каком-то фиксированном языке программирования. Так, например, у языков C++ и Python будет разная колмогоровская сложность одной программы.
Пример
Колмогоровская сложность программы, выводящей
():
for i = 1..n
print(0)
Теорема (Невычислимость Колмогоровской сложности): |
Колмогоровская сложность — невычислимая функция. |
Доказательство: |
, если только или — невычислима. Допустим, что p(): foreach x // перебираем слова по возрастанию длины if // теорема о рекурсии используется здесь print(x) exit Начиная с , . |
Busy beaver
Утверждение: |
Функция Busy beaver невычислима. |
Предположим, что это не так. Тогда напишем такую программу
p():
for i = 1..BB(
) + 1
do smth
Такая программа всегда совершает больше шагов, чем функция от этой программы. А это невозможно, так равна максимальному числу шагов как раз этой программы. Получили противоречие. |
Аналог I теоремы Гёделя о неполноте
Теорема: |
В любой "достаточно богатой системе" существует истинное недоказуемое утверждение. |
Доказательство: |
Поясним, что это значит. Так как любой язык программирования эквивалентен машине Тьюринга, то всё связанное с ним кодируется в логике первого порядка с аксиомами Пеано (для этого достаточно, чтобы программа умела прибавлять к числу единицу и вызывать подпрограммы), поэтому можно в терминах программ получать утверждения, эквивалентные тем, что строил Гёдель. Можно переформулировать теорему следующим образом: невозможно доказать, что .Таким образом напишем такую программу:
p(x):
foreach q
if q proves "p(x) зависает"
exit
|
Теорема о неподвижной точке
Зафиксируем главную нумерацию . Обозначим за множество слов, допускаемых программой с номером .
Утверждение: |
Напишем такую программу:
p(q): if p.getSrc() == q.getSrc() return 1 else while true Программа знает свой код, что то же самое, что и знает свой номер. Как видно из её кода, она допускает только одно число — свой номер. |