Почему программы не могут быть доказаны?

Почему компьютерная программа не может быть доказана так же, как математическое утверждение? Математическое доказательство строится на других доказательствах, которые строятся из еще большего числа доказательств и далее вплоть до аксиом - тех истин, которые мы считаем самоочевидными.

компьютерные программы, похоже, не имеют такой структуры. Если вы пишете компьютерную программу, как вы можете взять предыдущие проверенные работы и использовать их, чтобы показать правду вашей программы? Ты не можешь, потому что их не существует. Далее, что являются ли аксиомы программирования? Сами атомарные истины поля?

У меня нет хороших ответов на выше. Но кажется, что программное обеспечение не может быть доказано, потому что это искусство, а не наука. Как доказать Пикассо?

30 ответов


доказательства are программы.

формальная верификация программы это огромный научно-исследовательская зона. (См., например, группа в Карнеги-Меллон.)

многие сложные программы были проверены; например, см. Это ядро написано на языке Haskell.


программы абсолютно can доказано, что это правильно. Паршивые программы трудно доказать. Чтобы сделать это даже достаточно хорошо, вы должны разработать программу и доказательство рука об руку.

вы можете автоматизация доказательство из-за проблемы остановки. Однако вы можете вручную доказать постусловия и предварительные условия любого произвольного утверждения или последовательности утверждений.

вы должны прочитать Дийсктры дисциплина Программирование.

тогда, вы должны прочитать Грис' наука программирования.

тогда вы будете знать, как доказать правильность программ.


просто небольшой комментарий к тем, кто поднял неполноту-это не относится к все аксиоматические системы, только достаточно мощный те.

двойная проблема (пишу программы для проверки доказательств) также очень интересно.


проблемы остановки только показывает, что есть программы, которые не могут быть проверены. Гораздо интереснее и практичнее вопрос, какой класс программ can быть официально проверены. Возможно, каждая программа, о которой кто-то заботится, может (теоретически) быть проверена. на практике, до сих пор, только очень маленькие программы были доказаны правильными.


вы можете на самом деле писать правильных программ. Microsoft, например, создала расширение языка C# под названием Spec# который включает в себя автоматический доказатель теоремы. Для java существует ESC / java. Я уверен, что есть еще много примеров.

(редактировать: по-видимому, spec# больше не разрабатывается, но инструменты контракта станут частью .NET 4.0)

Я вижу, как некоторые плакаты размахивают руками о проблема останова или неполноте теоремы которые предположительно предотвращают автоматическую проверку программ. Это, конечно, не так; эти вопросы просто говорят нам, что это возможно писать программы, которые не могут быть доказаны как правильные или неправильные. Это не мешает нам создавать программы, которые are правильных.


Если вы действительно заинтересованы в теме, позвольте мне сначала порекомендовать "науку программирования" Дэвида Грайса, классическую вводную работу по этой теме.

на самом деле можно в какой-то степени доказать правильность программ. Вы можете написать предварительные условия и постусловия, а затем доказать, что данное состояние, которое соответствует предварительным условиям, результирующее состояние после выполнения будет соответствовать постусловиям.

где это становится сложным, однако, петли. Для этого вам кроме того, необходимо найти инвариант цикла и показать правильное завершение, вам нужно найти функцию верхней границы на максимально возможном количестве итераций, оставшихся после каждого цикла. Вы также должны иметь возможность показать, что это уменьшается по крайней мере на один после каждой итерации через цикл.

Если у вас есть все это для программы, доказательство механически. Но, к сожалению, невозможно автоматически получить инвариантные и связанные функции для циклов. Человеческий интуиции достаточно для тривиальных случаев с небольшими петлями, но реально сложные программы быстро становятся трудноразрешимыми.


во-первых, почему вы говорите, что "программы не могут быть доказаны"?

Что вы подразумеваете под" программами"?

Если программы вы значении алгоритмов не знаешь Краскала? Дийкстры? МСТ? Прим? Бинарный Поиск? Сортировка слиянием? ДП? Все эти вещи имеют математические модели, которые описывают их поведение.

описать. Математика не объясняет, почему вещи он просто рисует картину, как. Я не могу доказать тебе, что завтра солнце взойдет на Восток, но я могу показать данные, где он делал это в прошлом.

Вы сказали: "Если вы пишете компьютерную программу, как вы можете взять предыдущие проверенные работы и использовать их, чтобы показать правду вашей программы? Вы не можете, так как никто не существует"

ждать? Не можешь? http://en.wikipedia.org/wiki/Algorithm#Algorithmic_analysis

Я не могу показать вам "правду" Я программа столько же, сколько я не могу показать вам "правду" на языке. Оба представления о нашем эмпирическом понимании мира. Не на "правде". Отложив всю тарабарщину в сторону, я могу продемонстрировать вам математически, что алгоритм mergesort сортирует элементы в списке с производительностью O(nlogn), что Дийкстра найдет кратчайший путь на взвешенном графике или что алгоритм Евклида найдет вам наибольший общий делитель между двумя числами. "Правда в моей программе" в этом последнем случае, может быть, я найду вам самый большой общий делитель между двумя цифры, тебе не кажется?

с помощью рекуррентного уравнения я могу описать вам, как работает ваша программа Фибоначчи.

теперь, является ли компьютерное программирование искусством? Я, конечно, думаю. Сколько математики.


Я не из математического фона, так что простите мое невежество, но что означает "доказать программу"? Что ты доказываешь? Правильность? Правильность-это спецификация, которую программа должна проверить, чтобы быть "правильной". Но эта спецификация определяется человеком, и как вы проверяете правильность этой спецификации?

на мой взгляд, в программе есть ошибки, потому что у людей есть трудности с выражением того, что они действительно хотят. alt-текст http://www.processdevelopers.com/images/PM_Build_Swing.gif

Так что ты доказываешь? Ошибки, вызванные отсутствием внимания?


далее, каковы аксиомы программирования? Сами атомарные истины поля?

Я та объед курс названного договора Программирование (Домашняя страница курса: http://www.daimi.au.dk/KBP2/). Вот что я могу экстраполировать из курса (и других курсов я взял)

вы должны формально (математически) определение семантики языка. Давайте подумаем о простом языке программирования; тот, который имеет глобальные переменные только, Ints, int массивы, арифметика, if-then-else, while, назначение и ничего не делать [вы, вероятно, можете использовать подмножество любого основного языка в качестве "реализации" этого].

состояние выполнения будет список пар (имя переменной, значение переменной). Читать "{К1} С1 {К2}" как "инструкция С1 доставит вас из состояния выполнения Q1 в состояние В2".

одна аксиома тогда была бы "if both {Q1} S1 {Q2} and {Q2} S2 {Q3}, then {Q1} S1; S2 {Q3}". То есть, если оператор S1 принимает вас из состояния Q1 в Q2, а оператор S2 принимает вы от Q2 до Q3, затем "S1; S2" (S1, за которым следует S2) переводит вас из состояния Q1 в состояние Q3.

другой аксиомой было бы "if {Q1 && e != 0} S1 {Q2} and {Q1 && e == 0} S2 {Q2}, then {Q1} if e then S1 else S2 {Q2}".

теперь немного уточнения: Qn в {} на самом деле были бы заявлениями о состояниях, а не сами состояния.

предположим, что m (out, A1, A2) - это оператор, который выполняет слияние двух отсортированных массивов и сохраняет результат в out, и что все слова, которые я использую в следующем примере, были выражены формально (математически). Затем "{sorted(A1) && sorted(A2)} A := M(A1, A2) {sorted(A) && permutationOf(A, A1 concatened with A2)}" является утверждение tha M правильно реализует алгоритм слияния.

можно попытаться доказать это, используя приведенные выше аксиомы (возможно, потребуется несколько других. Вероятно, вам понадобится цикл, для одного).

Я надеюсь, что это иллюстрирует немного того, как могут выглядеть корректные программы. И поверьте мне: для этого требуется много работы, даже для казалось бы простых алгоритмов, чтобы доказать их правильность. Я знаю, я читал много попыток ;-)

[если вы прочтите это: код рука в порядке, это все другие, которые вызвали у меня головные боли ; -)]


конечно, они могут, как уже писали.

доказательство правильности очень маленькой подпрограммы-хорошее упражнение, которое IMHO каждый студент в программе, связанной с программированием, должен быть требуются сделать. Это дает вам отличное представление о том, как сделать ваш код понятным, легко просматриваемым и доступным для обслуживания.

в реальном мире он имеет ограниченное практическое применение.

во-первых, как и программы жуки, как и математические доказательства. Как доказать, что математическое доказательство действительно правильно и не имеет ошибок? Ты не можешь. И, например, в любом количестве опубликованных математических доказательств были обнаружены ошибки, иногда годы спустя.

во-вторых, вы не можете доказать правильность программы, не имея "априорного" однозначного определения того, что программа должна делать. Но любое однозначное определение того, что программа должна делать это программа. (Хотя это может быть программа на каком-то языке спецификаций, для которой у вас нет компилятора.) Поэтому, прежде чем вы сможете доказать, что программа правильна, вы должны сначала иметь другую программу, которая эквивалентна и заранее известна как правильная. Так что все это бесполезно.

Я бы рекомендовал отслеживать классический"Нет Серебряной Пули" статья Брукс.


есть много исследований в этой области.. как говорили другие, конструкции в программном языке сложны, и это только ухудшается при попытке проверить или доказать для любых заданных входных данных.

однако многие языки допускают спецификации, на какие входы допустимы (предварительные условия), а также позволяют указать конечный результат (условия post).

такие языки включают: B, событие B, Ada, fortran.

и, конечно, есть много инструменты, которые призваны помочь нам доказать определенные свойства программ. Например, чтобы доказать тупиковую свободу, можно было бы сжать их программу с помощью спина.

есть также много инструментов, которые помогают нам обнаруживать логические ошибки. Это можно сделать с помощью статического анализа (goanna, satabs) или фактического выполнения кода (gnu valgrind?).

однако, нет ни одного инструмента, который действительно позволяет доказать всю программу, от начала (спецификация), внедрение и развертывание. Метод B приближается, но проверка его реализации очень слаба. (Это предполагает, что люди infalible в переводе speicficaiton в реализации).


в качестве примечания, при использовании метода B вы часто будете создавать сложные доказательства из меньших аксиом. (И то же самое относится к другим доказательствам теоремы exhasustive).


Они могут. Я провел много, много часов, как первокурсник колледжа, делая доказательства правильности программы.

причина, по которой это не практично в макроуровне, заключается в том, что писать доказательство программы, как правило, намного сложнее, чем писать программу. Кроме того, программисты сегодня склонны создавать системы, а не писать функции или программы.

в микромасштабе я иногда делаю это мысленно для отдельных функций и, как правило, организовываю свой код, чтобы сделать их легкими для проверить.

есть известная статья о программном обеспечении космического челнока. Они делают доказательства или что-то подобное. Это невероятно дорого и отнимает много времени. Этот уровень проверки может быть необходим для них, но для любого потребителя или коммерческой компании программного обеспечения, с современными методами, вы получите свой обед съеденным конкурентом, который поставляет 99,9% - ное решение за 1% от стоимости. Никто не собирается платить $5000 за офис MS, который немного более стабилен.


Если вы ищете уверенность, альтернативой доказательству программ является их тестирование. Это легче понять и может быть автоматизирован. Он также допускает класс программ, для которых доказательства математически невозможны, как описано выше.

прежде всего, никакое доказательство не является заменой для прохождения приемочных испытаний:*

  • только потому, что программа действительно делает то, что она говорит, это не значит, что она делает то, что хочет пользователь это делать.

    • если вы можете доказать, что то, что он говорит, это то, что пользователь говорит, что они хотят.

      • который вы тогда должны доказать, что они действительно, потому что, будучи пользователем, они почти наверняка не знают, чего они хотят. так далее. Reductio ad absurdum.

*не упоминать блок, охват, функциональный, внедрение и все другие виды тесты.

надеюсь, это поможет вам на вашем пути.


что-то, что не было упомянуто здесь B-Метод который является формальной системой на основе метода. Он использовался для разработки системы безопасности Парижского метрополитена. Существуют инструменты для поддержки разработки B и Event B, в частности Родин.


вы не только можете доказать программы, вы можете позволить вашему компьютеру создавать программы из доказательств. См.Coq. Таким образом, вам даже не придется беспокоиться о возможности ошибки в вашей реализации.


теоремы Геделя несмотря ни на что...Какой в этом смысл? Какие упрощенные "истины" вы хотели бы доказать? Что бы вы хотели извлечь из этих истин? Пока я могу есть эти слова...где практичность?


программы могут быть доказаны. Это легко, если вы пишете их на языке, например, Standard ML of New Jersey (SML/NJ).


ваше заявление широко, поэтому он ловит много рыбы.

суть в том, что некоторые программы определенно могут быть доказаны правильно. Все программы могут не быть доказана.

вот тривиальный пример, который, заметьте, является точно таким же доказательством, которое уничтожило теорию множеств в тот день: сделайте программу, которая может определить, является ли она правильной, и если она найдет, что она is правильно, дайте неправильный ответ.

это теорема Геделя, простая и ясная.

но это не так проблематично, так как мы можем доказать многих программ.


предположим чисто функциональный язык (т. е. Haskell). Побочные эффекты могут быть приняты во внимание довольно чисто в таких языках.

доказательство того, что программа дает правильный результат, требует указать:

  1. соответствие между типами данных и математическими множествами
  2. соответствие между функциями Хаскелла и математическими функциями
  3. набор аксиом, определяющих, какие функции вы можете создавать из других, и соответствующая конструкция с математической стороны.

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

хорошей новостью является то, что" структура программ "(пункт 3 выше) и" структура математических множеств " довольно похожи (модное слово топос или декартово замкнутой категории), поэтому 1 / доказательства, которые вы делаете на математическая сторона легко будет перенесена в программные конструкции 2 / программы, которые вы пишете, легко показаны математически правильными.


читать на проблема останова (речь идет о трудности доказательства чего-то простого, например, завершается ли программа или нет). Принципиально проблема связана с теоремой Геделя о неполноте.


некоторые части программ могут быть доказаны. Например, компилятор C#, который статически проверяет и гарантирует безопасность типов, если компиляция завершается успешно. Но я подозреваю, что суть вашего вопроса заключается в том, чтобы доказать, что программа работает правильно. Многие (я не смею сказать большинство) алгоритмы могут быть доказаны правильно, но целая программа, вероятно, не может быть доказана статически из-за следующего:

  • проверка требует, чтобы все возможные ветви (вызовы, ifs и interupts) были проходится, что в расширенный программный код имеет супер-кубическую временную сложность (следовательно, он никогда не будет завершен в течение разумного срока).
  • некоторые методы программирования, либо путем создания компонентов, либо с помощью отражения, делает невозможным статически предсказать выполнение кода (т. е. вы не знаете, как другой программист будет использовать вашу библиотеку, и компилятор имеет трудное время предсказать, как отражение в потребителе вызовет функциональность.

и это только некоторые...


Если программа имеет четко определенные цели и исходные предположения (игнорируя Геделя... это можно доказать. Найдите все простые числа, x, для 6 программа, которая играет NIM (первая программа на Python я когда-либо писал) и теоретически компьютер всегда выигрывает после того, как игра попадает в состояние, в котором компьютер сможет выиграть. Я не смог доказать это как истину, но это правда (математически с помощью цифрового доказательства двоичной суммы) I поверьте, если я не ошибся в коде. Я сделал ошибку, нет серьезно, может кто-нибудь сказать мне, если эта программа является приемлемой?

есть некоторые математические теоремы, которые были "доказаны" с помощью компьютерного кода вроде теорема четырех цветов. Но есть возражения, потому что, как вы сказали, Вы можете доказать программу?


далее, каковы аксиомы программирования? Сами атомарные истины поля?

это opcodes "атомное истины"? Например, на зрение ...

mov ax,1

... не может ли программист утверждать как аксиому, что, исключая аппаратную проблему, после выполнения этого утверждения CPU ax регистрация теперь будет содержать 1?

если вы пишете компьютерную программу, как это можно взять предыдущие проверенные работы и использовать их, чтобы показать правду вашей программы?

"предыдущая работа" может быть средой выполнения, в которой выполняется новая программа.

новая программа может быть доказана: помимо формальных доказательств, она может быть доказана " проверкой "и различными формами" тестирования "(включая"приемочное тестирование").

как вы доказать Пикассо?

если программное обеспечение больше похоже на промышленный дизайн или инженерия, как и искусство, может быть лучшим вопросом: "как вы доказываете мост или самолет?"


доказательство правильности программы может быть сделано только относительно спецификации программы; это возможно, но дорого/трудоемко

некоторые системы CASE производят программы, более поддающиеся доказательствам, чем другие - но опять же, это опирается на формальную семантику спецификации...

...и как вы докажете правильность спецификации? Правильно! С больше спецификаций!


Я немного читал об этом, но есть две проблемы.

во-первых, вы не можете доказать какую-то абстрактную вещь, называемую правильностью. Вы можете, если все настроено правильно, доказать, что две формальные системы эквивалентны. Вы можете доказать, что программа реализует набор спецификаций, и это проще всего сделать, построив доказательство и программу более или менее параллельно. Поэтому спецификации должны быть достаточно подробными, чтобы обеспечить что-то, что можно доказать, и поэтому спецификация фактически является программой. Проблема написания программы для достижения цели становится проблемой написания формальной детальной спецификации программы для достижения цели, и это не обязательно шаг вперед.

во-вторых, программы являются сложными. Таковы доказательства правильности. Если вы можете ошибиться, написав программу, вы, конечно, можете сделать одно доказательство. Дийкстра и Грайс сказали мне, по сути, что если бы я был совершенным математик я мог бы быть хорошим программистом. Ценность здесь в том, что доказательство и программирование-это два несколько разных мыслительных процесса, и, по крайней мере, по моему опыту, я совершаю разного рода ошибки.

по моему опыту, доказывание программ не бесполезно. Когда я пытаюсь сделать что-то, что я могу описать формально, доказательство правильности реализации устраняет множество труднодоступных ошибок, в первую очередь оставляя глупые, которые я могу легко поймать в тестировании. На проекте это должно производить чрезвычайно свободный от ошибок код, это может быть полезным дополнением. Он не подходит для каждого применения, и это, конечно, не серебряная пуля.


как указывали другие, (некоторые) программы действительно могут быть доказаны.

одна проблема на практике, однако, заключается в том, что вам сначала нужно что-то (т. е. предположение или теорема), что вы хотите доказать. Поэтому, чтобы доказать что - то о программе, вам сначала нужно формальное описание того, что она должна делать (например, до и после условий).

другими словами, вам нужна формальная спецификация программы. Но получение даже разумного (гораздо менее строгого формального) спецификация уже является одной из самых сложных вещей в разработке программного обеспечения. Поэтому, как правило, очень трудно доказать Интересные о (реальных) программы.

однако есть некоторые вещи, которые могут быть (и были) более легко формализуются (и доказано). Если вы можете хотя бы доказать, что ваша программа не рухнет, это уже что-то: -).

кстати, некоторые предупреждения/ошибки компилятора по существу (простые) доказательства о программе. Например, компилятор Java докажет, что вы никогда не получаете доступ к неинициализированной переменной в коде (иначе это даст вам ошибку компилятора).


Я не читал все ответы, но, как я вижу, доказывать программы бессмысленно, поэтому никто этого не делает.

Если у вас есть относительно небольшой/средний проект (скажем, 10k строк кода), то доказательство, вероятно, будет также 10k строк, если не больше.

подумайте об этом, если программа может иметь ошибки, доказательство также может иметь "ошибки". Может быть, вам понадобится доказательство для доказательства!

еще одна вещь, чтобы рассмотреть, программы очень очень формальные и точный. Вы не можете получить более строгий и формальный, потому что программный код должен выполняться очень глупой машиной.

в то время как доказательства будут читаться людьми, поэтому они, как правило, менее строгие, чем фактический код.

единственное, что вы хотите доказать, это низкоуровневые алгоритмы, которые работают с конкретными структурами данных (например, quicksort, вставка в двоичное дерево и т. д.).

эти вещи несколько сложны, это не сразу очевидно, почему они работают и / или всегда будут работать. Они также являются базовыми строительными блоками для всех других программ.


большинство ответов сосредоточены на практике, и это нормально: на практике вы не заботитесь о формальной проверке. Но что теоретически?

программы могут быть доказаны так же, как математическое утверждение. Но не в том смысле, который вы имели в виду! В любой достаточно мощной структуре есть математические утверждения (и программы), которые не могут быть доказаны! См.здесь


здесь так много шума, но я все равно буду кричать на ветру...

"оправдаться" имеет разные значения в разных контекстах. В формальных систем, "доказать правильно" означает, что формула может быть получена из других доказанных (или аксиоматических) формул. "Доказать правильность" в программировании просто показывает, что код эквивалентен формальной спецификации. Но как вы докажете правильность формальной спецификации? К сожалению, нет способа показать спецификацию без ошибок или решение любого реальная проблема, отличная от тестирования.


только мои 2 цента, добавляя к интересному материалу уже там.

из всех программ, которые не могут быть доказаны, наиболее распространенными являются те, которые выполняют IO (некоторое непредсказуемое взаимодействие с миром или пользователями). Даже автоматические доказательства иногда просто забывают, что" проверенные" программы работают на каком-то физическом оборудовании, а не на идеальном, описанном моделью.

с другой стороны, математические доказательства не заботятся о мире. Повторяющийся вопрос с математикой если он описывает что-то реальное. Он возникает каждый раз, когда изобретается что-то новое, например мнимые числа или неевклидово пространство. Тогда вопрос забывается, так как эти новые теории являются такими хорошими инструментами. Как хорошая программа, она просто работает.