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


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

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

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

30 56

30 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

(edit: видимо 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 массивы, арифметика, если-то-еще, в то время как, назначение и ничего не делать [вы, вероятно, можете использовать подмножество любого основного языка в качестве "реализации" этого].

состояние выполнения будет список пар (имя переменной, значение переменной). Прочитайте "{Q1} S1 {Q2} " как "выполнение инструкции S1 переводит вас из состояния выполнения Q1 в состояние Q2".

одна аксиома была бы тогда "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 в {}'S На самом деле были бы заявлениями о состояниях, а не о самих состояниях.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

программы могут быть доказаны. Это тихо легко, если вы пишете их на языке, как, например, стандартный мл Нью-Джерси (SML/NJ).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

это коды операций "атомное истины"? Например на видя ...

mov ax,1

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

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

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

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

как вы докажете, Пикассо?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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