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


190

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

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

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

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

На самом деле, если бы это было не так, математика вряд ли была бы возможна, как мне кажется.

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

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

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

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

Другими словами, если шаг в доказательстве верен, то ошибка в шаге никогда не испортит шагНо если строка кода записана правильно, то ошибка в строке повлияет на работу строки , так что всякий раз, когда мы пишем строку мы должны учитывать ее отношение ко всем другим строкам. Мы можем использовать инкапсуляцию и все такое, чтобы ограничить это, но это не может быть полностью удалено.Y X X Y X XXYXXYXX

Это означает, что процедура проверки на ошибки в математическом доказательстве по существу линейна по количеству этапов доказательства, но процедура проверки на ошибки в компьютерном коде по существу экспоненциальна по количеству строк кода.

Как вы думаете?

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


3
Известны ли вам доказательства правильности программ, как на бумаге, так и механизированных в теоремах? Оба существуют и противоречат вашему обновлению. верно то, что программирование, как обычно преподают, имеет мало общего с программированием с доказательствами корректности.
Blaisorblade

76
Напоминает мне цитату Кнута, я думаю: «Остерегайтесь приведенного выше кода! Я только доказал его правильность, я никогда не проверял его»
Хаген фон

Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Жиль

7
Найдите мне написанное от руки математическое доказательство длиной 100 миллионов строк без "ошибок", и я дам вам все, что у меня есть.
Давор

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

Ответы:


226

Позвольте мне предложить одну причину и одно заблуждение в качестве ответа на ваш вопрос.

Основная причина , что проще писать ( по- видимому) правильные математические доказательства, что они написаны на очень высоком уровне. Предположим, что вы можете написать такую ​​программу:

function MaximumWindow(A, n, w):
    using a sliding window, calculate (in O(n)) the sums of all length-w windows
    return the maximum sum (be smart and use only O(1) memory)

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

Настоящим аналогом кода для математических доказательств являются компьютерные доказательства . Их гораздо сложнее разработать, чем обычные текстовые доказательства, и часто можно обнаружить различные скрытые углы, которые «очевидны» для читателя (который обычно даже не замечает их), но не так очевидны для компьютера. Кроме того, поскольку в настоящее время компьютер может заполнять только относительно небольшие пробелы, доказательства должны разрабатываться до такого уровня, чтобы читающий их человек пропустил бы лес за деревьями.

Важным заблуждением является то, что математические доказательства часто верны. На самом деле, это, вероятно, довольно оптимистично. Очень сложно писать сложные доказательства без ошибок, а статьи часто содержат ошибки. Пожалуй, наиболее известные недавние случаи - это первая попытка Уайлза (частный случай) теоремы модульности (которая подразумевает последнюю теорему Ферма), а также различные пробелы в классификации конечных простых групп, включая более 1000 страниц на квазитиновых группах, которые были написано через 20 лет после того, как классификация была якобы закончена.

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


Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
DW

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

3
@AlexVong Одна из проблем заключается в том, что написание формальной спецификации для нетривиального кода (чтобы вы могли убедиться, что код действительно соответствует спецификации) практически невозможно. Например, можете ли вы представить, насколько сложной будет формальная спецификация для браузера (включая все взаимодействия с пользователем, все поддерживаемые форматы файлов и протоколы и т. Д.)?
svick

2
@svick Вы правы, для взаимодействия с пользователем иногда даже не ясно, каким должно быть правильное поведение. Поэтому мы должны вместо этого сосредоточиться на чем-то с надлежащей формальной спецификацией (например, доказательство, компилятор).
Алекс Вонг

1
На самом деле. Это также может быть объяснением того, почему многие люди находят кодирование на языках нижнего уровня гораздо более утомительным и менее увлекательным, чем кодирование на абстрактных языках высокого уровня. Хотя, конечно, это может также отличаться в зависимости от человека (Некоторым может даже нравиться создавать аппаратные / электронные схемы очень низкого уровня больше, чем писать программное обеспечение, которое работает на них? Кроме того, код низкого уровня все еще может быть незаменим во многих случаях и писать его хорошо может быть недостаточным навыком / умением, достойным похвалы самостоятельно).
xji

77

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

Идея, которая, как я полагаю, не особенно отличается от существующего ответа, заключается в том, что «доказательство» или аргумент сообщается математическому сообществу, цель которого состоит в том, чтобы убедить их в том, что (утомительные) детали могут быть заполнены, в принципе, получить полностью определенное формальное доказательство - не делая этого вообще. Одним из важных примеров этого является то, что вы можете использовать существующие теоремы, просто указав их, но повторное использование кода в целом гораздо сложнее. Также рассмотрим незначительные «ошибки», которые могут полностью сделать часть кода бесполезной (например, это SEGFAULT), но могут оставить математический аргумент в значительной степени нетронутым (то есть, если ошибка может содержаться без свертывания аргумента).

Стандарт правильности и полноты, необходимый для того, чтобы заставить компьютер работать вообще, на пару порядков выше, чем стандарт действительных доказательств математического сообщества. Тем не менее, большие компьютерные программы, даже если они были очень тщательно написаны и очень тщательно протестированы, всегда имеют ошибки. [...] Математика, поскольку мы практикуем это, намного более формально полна и точна чем другие науки, но это намного менее формально полна и точна по своему содержанию, чем компьютерные программы. Разница связана не только с количеством усилий: вид усилий качественно другой. В больших компьютерных программах огромная часть усилий должна быть потрачена на множество вопросов совместимости: обеспечение согласованности всех определений, разработка «хороших» структуры данных, которые имеют полезную, но не громоздкую общность, выбирают «правильную» общность для функций и т. д. Доля энергии, затрачиваемой на рабочую часть большой программы, в отличие от бухгалтерской части, удивительно мала. Из-за проблем совместимости, которые почти неизбежно обостряются из-за того, что «правильные» определения меняются по мере добавления общности и функциональности, компьютерные программы обычно приходится часто переписывать, часто с нуля.

ДОКАЗАТЕЛЬСТВО И ПРОГРЕСС В МАТЕМАТИКЕ (с. 9-10), УИЛЬЯМ П. ТЕРСТОН https://arxiv.org/pdf/math/9404236.pdf


3
Пункт о «повторном использовании кода» вполне уместен. Перевод длинного доказательства с русского на английский требует довольно много печатания ; но перевод большой компьютерной программы, скажем, с C ++ на Java, требует много размышлений . Кроме того, возродить 3000-летнее доказательство в древнегреческом также просто; Воскрешение 30-летней программы в PL / 1 примерно так же сложно или сложно.
Quuxplusone

2
Древнегреческий пример также заставил меня осознать: программисты используют тонну местного сленга и разговорных выражений, таких как (void*)1и open('/dev/null'), которые могут даже не быть переносимыми между различными субкультурами, не говоря уже о переводе на язык назначения. (Читатель просто должен уловить их приблизительную семантику благодаря многолетнему опыту.) Я думаю, что математические доказательства содержат меньше такого «сленга». Если доказательство использует слово, его фактический универсальный смысл должен быть выводимым читателем как - то. Компьютерные программы даже не имеют универсального значения!
Quuxplusone

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

@ Нат можешь уточнить? Я не понимаю
Григорий Магаршак

@GregoryMagarshak Этот ответ продемонстрировал случай, когда допущение, что бесконечность действительна в построении серий, приводит к ошибке, которую я описывал как эту скрытую ошибку00замаскированная » версия ниже в Википедии) раздел). Классический математик мог бы сказать, что ошибка заключалась в предположении, что бесконечный ряд сходится, хотя конструктивист описал бы ошибку как безусловную презумпцию бесконечности.
Nat

55

Позвольте мне начать с цитирования EW Dijkstra:

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

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

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

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

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

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

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

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


Обратите внимание, что ваша гипотеза написания безошибочных доказательств проще, чем безошибочные программы (которые на самом деле являются разными утверждениями, как указывает @Ariel ), на самом деле может быть неверной, поскольку доказательства часто создаются методом проб и ошибок на каком-то уровне. Тем не менее, я надеюсь, что это проливает некоторый свет на вопрос, который подразумевается: «В чем на самом деле разница между доказательством некоторой теоремы и написанием программы?» (На что неосторожный наблюдатель переписки Карри-Говарда может сказать: «Ничего!»)


Как упомянуто в комментариях @wvxvw, следующие параграфы «заметок по структурированному программированию» (EWD249, стр. 21) очень актуальны:

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

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


2
Я просто мирянин; Что Дейкстра на самом деле называл «программированием»?
Ovi

2
@ Ovi Я не совсем уверен, но главное отличие в том, что он говорит о (нетривиальных) алгоритмических задачах, решающих больше, чем «общие» задачи программирования, то есть он, конечно, не говорит о какой-то программе CRUD, которая должна соединять некоторые существующие архитектуры или другие компоненты и т. д. Подробнее о мнении Дейкстры о программировании можно узнать из этого ответа
Дискретная ящерица

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

@ Ови, я думаю по твоему вопросу, что программирование во времена Дейкстры чаще означало написание ассемблерного кода, чем современную эру языков высокого уровня. Точно так же, я читаю издание Mythical Man-Month 1974 года, концепции все еще актуальны, но технические ссылки - это ассемблер системного уровня или PL / I, сильно отличающийся от того, что большинство людей считает программированием сегодня
JimLohse

46

Лампорт дает основания для разногласий по поводу распространенности ошибок в доказательствах в разделе Как написать доказательство (стр. 8-9) :

Около двадцати лет назад я решил написать доказательство теоремы Шредера-Бернштейна для вводного курса математики. Самое простое доказательство, которое я смог найти, было в классическом тексте общей топологии Келли. Поскольку Келли писал для более искушенной аудитории, мне пришлось добавить немало объяснений к его полстраничному доказательству. Я написал пять страниц, когда понял, что доказательство Келли неверно. Недавно я хотел проиллюстрировать лекцию о моем стиле доказательства убедительным неверным доказательством, поэтому я обратился к Келли. Я не мог найти ничего плохого в его доказательстве; это казалось очевидно правильным! Чтение и перечитывание доказательства убедили меня в том, что либо моя память испортилась, либо я был очень глупым двадцать лет назад. Тем не менее, доказательство Келли было коротким и послужило хорошим примером, поэтому я начал переписывать его как структурированное доказательство.

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


6
Та же статья: «Согласно неофициальным данным, треть публикаций, опубликованных в математических журналах, содержат ошибки - не только незначительные ошибки, но и неверные теоремы и доказательства». Ну, это было в 90-х, но сегодня ли это по-другому? Вероятно, те документы, которые существовали в те дни, все еще существуют, и все накапливается ... Итак, я не совсем уверен, что математические доказательства, представленные в статьях, содержат меньше ошибок.
MarkokraM

Увлекательный анекдот, но я не вижу, чтобы он прямо отвечал или занимался вопросом. Хотели бы вы отредактировать свой ответ, чтобы более прямо ответить на заданный вопрос? Вы утверждаете, что математические доказательства так же ошибочны, как написание компьютерного кода? Есть ли у вас дополнительные доказательства того, что вы можете предоставить? Анекдот или два на самом деле не демонстрируют это, не так ли?
DW

@WW Я посылаю электронное письмо Лесли, если он может предоставить дополнительные доказательства для иска.
MarkokraM

3
@DW Leslie сказал в своем искреннем ответе, что его коллега провел расследование с 51 доказательством, опубликованным в Math Reviews в то время. По его мнению, это более чем анекдотично, но не подходит для веских доказательств из-за нескольких фактов. Дело было более сложным, потому что некоторые ошибки в доказательствах возникали, потому что они использовали ошибочные доказательства в ранее опубликованных статьях и т. Д. Это было бы отличной темой для исследования, но требует такой большой работы. Как проверить математические доказательства программно - все еще огромный вопрос. Приложения, созданные для интерактивной помощи, находятся на ранней стадии. По крайней мере, интерфейс их.
MarkokraM

@DW Один или два анекдота демонстрируют, как математическое доказательство может показаться «правильным», но на самом деле неубедительным. Каждому, кто написал сложный компьютерный алгоритм и сделал математическое доказательство, и попытался написать компьютерный алгоритм как математическое доказательство, а затем обнаружил, как «алгоритм» высокого уровня предается многими, многими ошибками в деталях, результат совсем не удивительно.
Якк

39

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

Сравните это с компьютерной программой, которая должна обеспечить «правильный» вывод для диапазона возможных входов. Редко можно перечислить все входные данные и попробовать их все. Что еще хуже, предположим, что программа взаимодействует с человеком и позволяет их вкладу изменять функционирование? Люди, как известно, непредсказуемы, и число возможных вкладов в достаточно большую программу взаимодействия с людьми растет невероятными темпами. Вы должны попытаться предвидеть все различные способы использования программы и попытаться заставить все эти варианты использования либо работать, либо, по крайней мере, терпеть неудачу разумным образом, когда отказ является единственным вариантом. И это при условии, что вы даже знаете, как это должно работать во всех этих непонятных угловых случаях.

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


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

6
На практике другая проблема с потребительским программным обеспечением заключается в том, что «правильное» поведение часто плохо определяется заранее, и поэтому то, что раньше было правильным, становится неправильным. Это все равно что пытаться написать доказательство, только чтобы узнать, что люди решили изменить аксиомы. Вы можете исправить это в записи, не так ли?
Дэн Брайант

2
@DanBryant Такая ситуация случается в математике. В частности, определения терминов изменяются во времени и часто неоднозначны даже при использовании. «Доказательства и опровержения» Имре Лакатоса описывают это термином «многоугольник». Аналогичная вещь произошла с «функцией» и, в меньшей степени, с «интегралом». Даже сегодня «категория» не является однозначной, и доказательства и теоремы могут потерпеть неудачу в зависимости от того, что именно вы имеете в виду.
Дерек Элкинс

25

Они говорят, что проблема с компьютерами в том, что они делают именно то , что вы им говорите.

Я думаю, что это может быть одной из многих причин.

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

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

Например, скажем, это шаг в каком-то доказательстве:

x2+4x+3x+3=(x+1)(x+3)x+3=x+1

x2+4x+3x+3x=3


3
Отличный ответ! за исключением того, что как компьютер я возражаю против использования вами слова «без необходимости». ;) [Предположим, что это был всего лишь один шаг в большем доказательстве с целью доказать, что -xоно составное. Тот факт, что этот шаг неверен, когда -x = 3очень важен для правильности завершенного доказательства!]
Quuxplusone

@Quuxplusone: = P
Мердад

Компьютеры также могут использовать правила символьной математики и недетерминированного переписывания, просто языки, которые мы используем, такие как C ++, очень и очень низкого уровня и основаны на древней технологии (например, C имел меньше возможностей, чем Algol 60). Единственными исключениями являются языки проверки / проверки, такие как Idris / Agda, Lisp с символическими решателями и Mathematica. ja.wolframalpha.com/input/...
aoeu256

23

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

nn!

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

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


18

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

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

Что если математическое доказательство может дать разные результаты, если оно было прочитано во вторник или когда год перешел к 2000 году с 1999 года? Что если часть математического доказательства состояла в том, чтобы вернуться на несколько страниц назад, переписать несколько строк, а затем начать заново с этого момента?

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

Я вижу и другие вторичные факторы:

  1. Математики, как правило, гораздо более образованны, чем пытаться написать значительное / публикуемое доказательство. 1/4 профессиональных разработчиков с одноименным названием начали писать код менее 6 лет назад (см. Опрос SO 2017 ), но я предполагаю, что большинство математиков имеют более десяти лет формального математического образования.
  2. Математические доказательства редко проводятся на том же уровне, что и компьютерный код. Одна опечатка может / сломает программу, но десятки опечаток могут оказаться недостаточными для уничтожения значения доказательства (только его читаемости).
  3. Дьявол кроется в деталях, а компьютерный код не может пропустить детали. Доказательства могут свободно пропустить шаги, которые считаются простыми / рутинными. Есть несколько хороших синтаксических сахаров, доступных на современных языках, но они жестко запрограммированы и довольно ограничены по сравнению.
  4. Математика старше и имеет более прочную основу. Конечно, в математике есть множество новых и блестящих подполей, но большинство основных принципов использовалось в течение десятилетий. Это приводит к стабильности. С другой стороны, программисты по-прежнему не согласны с базовой методологией кодирования (просто спросите о гибкой разработке и скорости ее принятия).

Стоит упомянуть, что программным эквивалентом «независимости» является функциональная чистота , которая признается и поддерживается в некоторых языках, таких как Haskell.
Pharap

12

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

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

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

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

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

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

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

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


Я на самом деле не уверен, кто хуже, чем программисты и математики, формально (т.е. проверяющим машины) формулирует спецификации корректности и проверяет правильность кода, скажем, для программы 10KLOC или более крупной. С одной стороны, вы совершенно правы в том, что большинство программистов не имеют хорошо разработанных навыков доказательства теорем. С другой стороны, большие формальные доказательства похожи на большие программы, и для управления ими необходимы навыки разработки программного обеспечения. Я полностью уверен, что любое неофициальное доказательство правильности такой программы не будет иметь никакой надежды на то, чтобы быть правым.
Дерек Элкинс

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

11

Уже есть много хороших ответов, но есть еще много причин, по которым математика и программирование не совпадают.

1 Математические доказательства, как правило, гораздо проще, чем компьютерные программы. Рассмотрим первые шаги гипотетического доказательства:

Пусть a будет целым числом

Пусть b будет целым числом

Пусть с = а + б

Пока доказательство в порядке. Давайте превратим это в первые шаги аналогичной программы:

Пусть a = input ();

Пусть b = input ();

Пусть с = а + б;

У нас уже есть множество проблем. Предполагая, что пользователь действительно ввел целое число, мы должны проверить границы. Является ли больше , чем -32768 (или что - то минимальное ИНТ на вашей системе)? Является менее чем 32767? Теперь мы должны проверить то же самое для б . И поскольку мы добавили a и b, программа не верна, если только a + bбольше -32768 и меньше 32767. Это 5 отдельных условий, которые программист должен беспокоиться о том, что математик может игнорировать. Программист должен не только беспокоиться о них, он должен выяснить, что делать, если одно из этих условий не выполнено, и написать код, который он решит, как только он решит эти условия. Математика проста. Программирование сложно.

2 Спрашивающий не говорит, имеет ли он в виду ошибки времени компиляции или ошибки времени выполнения, но программистам, как правило, просто наплевать на ошибки времени компиляции. Компилятор находит их, и их легко исправить. Они как опечатки. Как часто люди вводят несколько абзацев без ошибок в первый раз?

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


10

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

  • Функции в Math чистые (весь результат вызова функции полностью инкапсулирован в возвращаемое значение, которое является детерминированным и полностью вычисляется из входного значения).
  • Математика не имеет мутации или переназначения (когда вам нужно моделировать такие вещи, используются функции и последовательности).
  • Математика прозрачна по ссылкам (например, нет указателей, нет понятия «вызов по имени» или «вызов по значению»), а математические объекты имеют семантику равенства экстенсиональности (если «две» вещи одинаковы во всех наблюдаемых способах, то они фактически тоже самое).

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


7

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

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

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

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

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


Или, чтобы быть более кратким :

введите описание изображения здесь


4

Глядя на это с другой стороны, в неакадемических условиях это часто сводится к деньгам.

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

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

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


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

Честный комментарий. Я, вероятно, неправильно использую некоторую терминологию, поскольку это не мое академическое образование. Хотя я чувствую, что предполагать, что другие компоненты безупречны, это не мудрый поступок из-за моих предыдущих комментариев.
navigator_

4

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

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

В том же настроении я хотел бы обратить внимание читателя на тот факт, что «ясность» имеет ярко выраженные количественные аспекты, о чем многие математики, как ни странно, не подозревают. Теорема, утверждающая обоснованность заключения, когда удовлетворены десять страниц, полных условий, вряд ли является удобным инструментом, поскольку все условия должны проверяться всякий раз, когда теорема обращается к. В евклидовой геометрии теорема Пифагора справедлива для любых трех точек A, B и C, таких, что через A и C прямую линию можно провести ортогонально прямой через B и C. Сколько математиков считают, что теорема остается применимой, когда некоторые или все точки A, B и C совпадают? все же это кажется в значительной степени ответственным за удобство использования теоремы Пифагора.

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

Это слегка отредактированные последние три абзаца из первой главы структурированного программирования Дейкстры.

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


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

@YuvalFilmus, как в цитате: десять страниц утверждений для людей длинны. Как я могу судить о длине программы? Что ж, Дикстра предложила метрику: длину ее текста. Я думаю, что это может быть слишком упрощенно, но, тем не менее, это хорошая эвристика. Есть и другие, более интересные метрики, такие как, например, цикломатическая сложность
wvxvw

3

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

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

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


3
Подождите, что заставляет вас думать, что математики "полностью понимают" доказательства и леммы, которые они используют? Я не уверен, какую разницу между математиками и программистами вы пытаетесь продемонстрировать здесь.
Дерек Элкинс

3

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

Программы являются доказательствами

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

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

В качестве примечания: «Музыка потоков» - один из самых красивых мостов между ними. Это в основном создает вещи , чтобы быть в состоянии сказать : «Я хочу это в том , как» и машина магическим образом делает это именно так , как хотелось бы .


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

Я знаю, что это немного надумано для C или подобных вещей. Но моя точка зрения такова: математика ближе, чем может подумать типичный новичок в CS!
Олег Лобачев

1
Кажется, вы - «неосторожный наблюдатель» изоморфизма Карри-Ховардса, о котором я говорил в своем ответе. Даже если у нас есть изоморфизм между программами и доказательствами, из этого не следует, что процесс написания программ и написания доказательств вообще похож. Фактически, может даже случиться, что все «интересные» или «типичные» программы не соответствуют типичным доказательствам, и наоборот.
Дискретная ящерица

@Discretelizard Это явно не тот случай, когда «интересные» программы не соответствуют «типичным доказательствам». Вот пример , где я беру чью - то «типичное доказательство» и произвести (эскиз) бесспорно интересную программу (что - то тесно связано с методом исключения Гаусса). Я думаю, что большинство «интересных» программ были бы полезными леммами или теоремами, но с достаточно точными типами, но многие (конструктивные) доказательства не имеют реального вычислительного значения - они просто проверяют побочные условия - хотя очень многие это делают.
Дерек Элкинс

3

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

π


2
«Математические доказательства оперируют воображаемыми вычислительными системами, которые имеют бесконечную память и бесконечную вычислительную мощность». Большинство математических доказательств «оперируют» формальными алгебраическими системами, например, действительными числами (где мы имеем «бесконечную точность»). Это также может быть сделано в программах: существуют так называемые системы компьютерной алгебры (CAS), которые делают именно это! Кроме того, целые области математики связаны с тем фактом, что мы не можем представлять все действительные числа в точности как конечные числа с плавающей запятой. Я думаю, что вы делаете различие между математикой и программированием, где их нет.
Дискретная ящерица

1
@Discretelizard, да, специальные пакеты существуют с произвольной точностью, но даже в этом случае доступная память ограничит фактическую достижимую точность. Также они являются специальными пакетами. Лишь небольшая часть программирования выполняется с такими пакетами, и в основном в академической среде.
crobar

π

@Discretelizard, я думаю, что моя точка зрения остается в силе, большинство программистов не используют такие системы CAS. Они слишком медленные для реального программирования. Большая часть программирования в основном включает операции с числами с ограниченной точностью. Главными языками являются C, C ++, Python, Java и т. Д. Ни один из них не использует представление стиля CAS по умолчанию (хотя пакеты для этого могут быть созданы в них). Ваш контрпример - крошечное нишевое подмножество компьютерных языков / систем.
crobar

2
@crobar Проблема с вашим ответом состоит в том, что подавляющее большинство обнаруженных ошибок не связано с ошибками с плавающей запятой или целочисленными переполнениями (хотя они вносят приличное число, и эти аспекты определенно делают полную корректность программы гораздо более маловероятной). Однако вы можете сделать более общее утверждение о том, что математикам не хватает многих проблем программистов, таких как производительность, время выхода на рынок, удобство обслуживания и ограниченная способность изменять требования, если они оказываются слишком сложными.
Дерек Элкинс

3

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

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

И действительно, математика может получить BSOD! Это был бы не первый раз!

введите описание изображения здесь

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

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

Давайте не будем слишком жалеть Гильберта , он знал, во что ввязался. Это просто бизнес.

Если вы хотите быть по-настоящему уверенным, принимайте все на индивидуальной основе и делайте свои собственные выводы!


3

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

1: программы содержат переменные или динамические объекты, изменяющиеся со временем, тогда как математические объекты в доказательствах обычно являются статическими. Таким образом, нотация в математике может быть использована в качестве прямой поддержки рассуждений (и если a = b, это остается так), где это не работает в программах. Кроме того, эта проблема усугубляется, когда программы параллельны или имеют несколько потоков.

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


3

Вы должны различать две разные «категории»:

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

Мы использовали псевдокод в течение тысяч лет (например, алгоритм Евклида). Написание формального кода (на формальных языках, таких как C или Java) стало чрезвычайно популярным и полезным после изобретения компьютеров. Но, к сожалению, формальные доказательства (на официальных языках, таких как Principia Mathematica или Metamath) не очень популярны. И поскольку сегодня все пишут псевдо-доказательства, люди часто спорят о новых доказательствах. Ошибки в них можно обнаружить спустя годы, десятилетия или даже столетия после фактического «доказательства».


3

Я не могу найти ссылку, но я думаю, что Тони Хоар однажды сказал что-то вроде следующего: Разница между проверкой программы и проверкой доказательства состоит в том, что доказательство может проверяться двумя строками одновременно.

Одним словом: местность.

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

Рассмотрим эту программу, где х только для чтения

    assume x >= 0
    p := 0 ;
    var pp := 0 ;
    while( x >= pp + 2*p + 1 ) 
    {
        var q := 1 ;
        var qq := q ;
        var pq := p ;
        while(  pp + 4*pq + 4*qq <= x )
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

Это легко выполнить, но сложно проверить.

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

    assume x >= 0
    p := 0 ;
    var pp := 0 ; 
    while( x >= pp + 2*p + 1 ) 
        invariant p*p <= x 
        invariant pp == p*p
        decreases x-p*p 
    {
        var q := 1 ;
        var qq := q ; 
        var pq := p ; 
        while(  pp + 4*pq + 4*qq <= x )
            invariant (p+q)*(p+q) <= x
            invariant q > 0 
            invariant qq == q*q 
            invariant pq == p*q 
            decreases x-(p+q)*(p+q)
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        assert (p+q)*(p+q) <= x and pp==p*p and pq==p*q and qq==q*q and q>0
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

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

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


2

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

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

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


3
Два года математики на уровне колледжа не означают два года, посвященных написанию доказательств (или тратят какое-то время на написание доказательств). Тем не менее, у меня сложилось впечатление, что классы геометрии в средней и ранней школе обычно включают доказательства, поэтому, очевидно, мы можем ожидать, что даже 13-летние дети смогут писать простые доказательства с меньшим, чем школьный год обучения, на тема. Пошаговые алгебраические вычисления также являются существенными доказательствами. Я думаю, что вы ставите планку «тривиально» для программирования слишком низко и для доказательства слишком высоко.
Дерек Элкинс

3
Мы могли бы писать программы таким же образом. Вы можете представить себе требование, чтобы каждая функция / процедура, которую вы пишете, предоставляла формальную спецификацию и доказательство (скажем, в Coq), что она соответствует спецификации. Тогда есть способы проверить правильность этого доказательства таким образом, чтобы не требовалось никакого суждения или понимания.
DW

@DW: Вы предполагаете, что (1) желаемое поведение может быть полностью задано во всех случаях, (2) существует необходимое доказательство (т. Е. Проблема не является неразрешимой), и (3) если доказательство существует, то мы могу найти это. Я думаю, что все три из этих предположений являются ложными по крайней мере в некоторых случаях (вероятно, почти во всех случаях). В отношении 3 отметим, что хотя некоторые доказательства могут быть простыми, многие доказательства найти очень сложно.
Бен Кроуэлл

@DerekElkins: Мое утверждение, что очень немногие студенты колледжа могут написать даже тривиальные доказательства, основано на моем собственном опыте работы со студентами. Это в общественном колледже, так что YMMV. Тот факт, что некоторые классы по геометрии в средней школе включают в себя большую дозу корректуры, не означает, что все студенты колледжа могут писать доказательства. Предполагается, что они также знают, как выполнять базовую алгебру, но в моей школе примерно половина студентов-первокурсников не могут - что помогает объяснить, почему многие из них терпят неудачу.
Бен Кроуэлл

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

2

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

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


1
«Только небольшая часть математических утверждений, которые являются правдой, может быть практически доказана». - Как вы измеряете «порцию»? Это при некотором распределении вероятностей? У вас есть доказательства, подтверждающие это утверждение?
DW

«Компьютеры часто призваны делать что-то, что выходит за рамки того, что может обеспечить правильное программное обеспечение». - Есть ли у вас доказательства этого? У вас есть пример? Вы заявляете, что «за пределами того, что в принципе может быть доказано правильно» или «за пределами того, что мы можем разумно представить, доказывая на практике»?
DW

@DW: Если X и Y являются ортогональными утверждениями, которые являются истинными, но не доказуемыми, то для каждого доказуемого утверждения P будет как минимум два ортогональных утверждения (P и X) и (P и Y), которые являются истинными, но не являются -provable. При работе с бесконечными множествами такая логика не обязательно что-либо доказывает, поскольку можно использовать аналогичную логику, чтобы показать, что четных целых чисел в два раза больше, чем нечетных целых, поскольку для каждого нечетного целого числа можно идентифицировать два четных целых числа (4x) и (4x + 2), которые не связаны с другими нечетными целыми числами, но, конечно, четные и нечетные целые имеют одинаковую мощность.
суперкат

@DW: фраза «малая часть», таким образом, может иметь смысл только при описании той части истинных утверждений, которая может быть практически доказана, но я думаю, что полезно понимать, что невозможность доказать все истинные утверждения не является «недостатком». Что касается компьютеров, многие поля обычно используют алгоритмы, которые имеют чрезвычайно малую, но ненулевую вероятность отказа, а затем настраивают их так, чтобы вероятность была приемлемо низкой (например, ниже, чем у оборудования, пораженного метеором). Однако во многих случаях различные режимы сбоя не являются независимыми, поэтому это может быть практически невозможно ...
суперкат

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

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

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

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

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


2

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

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

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

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

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

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


1

Вы честно сравниваете здесь яблоки и апельсины. Безотказный и без ошибок не одно и то же.

Если программа сравнивает числа 2и 3говорит, что 2 is greater than 3это может быть связано с ошибкой реализации:

# Buggy implementation
function is_a_greater_than_b(a,b):
  return b > a

Программа по-прежнему без ошибок, хотя. Сравнивая два числа aи b, он всегда сможет сказать вам, bбольше ли он a. Это просто не то, что вы (программист) должны были попросить сделать компьютер.


2
Каково ваше определение "ошибка" в программе тогда?
user56834

0

а) Потому что компьютерные программы больше, чем математические доказательства

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

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

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

Дополнительно:

NASA:

Это программное обеспечение не содержит ошибок. Он совершенен, настолько совершенен, насколько достигли люди. Посмотрите на эту статистику: последние три версии программы - каждая длиной 420 000 строк - имели только одну ошибку в каждой. Последние 11 версий этого программного обеспечения имели в общей сложности 17 ошибок.

Возьмите обновление программного обеспечения, чтобы позволить шаттлу перемещаться с помощью спутников глобального позиционирования, изменение, которое затрагивает всего 1,5% программы или 6 366 строк кода. Спецификации для этого изменения составляют 2500 страниц, объем которых больше, чем у телефонной книги. Спецификации для текущей программы заполняют 30 томов и занимают 40000 страниц.

https://www.fastcompany.com/28121/they-write-right-stuff


«Компьютерные программы больше, чем математические доказательства» Это зависит от программы и доказательства. И многое из этого кажется очень умозрительным.
Дэвид Ричерби

@DavidRicherby хорошо, я имел в виду такие вещи, как теорема Последнего Ферма и Apollo github.com/chrislgarry/Apollo-11 math.wisc.edu/~boston/869.pdf НАСА, и мы даже не говорим об операционных системах и так далее.
Exeus

0

Основные уровни:

Давайте посмотрим на вещи на самом простом и самом базовом уровне.

По математике имеем:
2 + 3 = 5

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

Для компьютерного программирования большинство людей склонны использовать язык высокого уровня. Некоторые языки высокого уровня могут даже «компилироваться» в один из языков низкого уровня, например, C. Затем можно перевести на язык ассемблера. Затем язык ассемблера преобразуется в машинный код. Многие думают, что на этом сложность заканчивается, но это не так: современные процессоры принимают машинный код за инструкции, а затем запускают «микрокод», чтобы фактически выполнить эти инструкции.

Это означает, что на самом базовом уровне (имея дело с простейшими структурами) мы сейчас имеем дело с микрокодом, который встроен в аппаратное обеспечение и который большинство программистов даже не использует напрямую и не обновляет. На самом деле, не только большинство программистов не касаются микрокода (на 0 уровней выше, чем микрокод), большинство программистов не касаются машинного кода (на 1 уровень выше микрокода) и даже сборки (на 2 уровня выше, чем микрокод) ( кроме, возможно, для небольшого формального обучения в колледже). Большинство программистов будут тратить время только на 3 или более уровней выше.

Кроме того, если мы посмотрим на сборку (которая является настолько низкой, насколько обычно получают люди), каждый отдельный шаг обычно понятен людям, которые прошли обучение и имеют ресурсы для интерпретации этого шага. В этом смысле Assembly намного проще, чем язык более высокого уровня. Тем не менее, сборка настолько проста, что выполнять сложные задачи или даже посредственные задачи очень утомительно. Языки верхнего уровня освобождают нас от этого.

В законе о «обратном проектировании» судья заявил, что даже если теоретически можно обрабатывать код по одному байту за раз, современные программы занимают миллионы байтов, поэтому некоторые виды записей (например, копии кода) должны создаваться только для таких целей. усилие быть выполнимым. (Поэтому внутренняя разработка не считалась нарушением обобщенного правила об авторском праве «не делать копии».) (Возможно, я думаю о создании несанкционированных картриджей Sega Genesis, но, возможно, думаю о чем-то, что было сказано во время дела Game Genie. )

Модернизация:

Вы запускаете код, предназначенный для 286? Или вы запускаете 64-битный код?

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

Стандарты используемых инструментов:

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

На практике я обнаружил, что с помощью JScript в Windows Script Host я смог добиться много хорошего, используя объекты. (Мне нравится среда, потому что набор инструментов, необходимый для тестирования нового кода, встроен в современные версии Microsoft Windows.) При использовании этой среды я обнаружил, что иногда нет легко найти документацию о том, как работает объект. Однако использование объекта настолько выгодно, что я все равно это делаю. Итак, я бы написал код, который может быть ошибочным, как гнездо шершня, и делать это в хорошо изолированной среде, где я могу видеть эффекты и узнавать о поведении объекта во время взаимодействия с ним.

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

В таких сценариях я полагаюсь на OpenBSD, созданный опытными программистами, которые регулярно создают новые выпуски по расписанию (два раза в год), с известной историей безопасности «только две удаленные дыры» за 10+ лет? (Даже у них есть исправления для менее серьезных проблем.) Нет, ни в коем случае. Я не полагаюсь на такой продукт с таким высоким качеством, потому что я работаю в бизнесе, который поддерживает предприятия, которые поставляют людям компьютеры, использующие Microsoft Windows, и именно поэтому мой код должен работать.

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

Резюме

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

Неожиданно я могу вспомнить удивление, насколько короткими были некоторые очень полезные и популярные функции, когда я увидел некоторый исходный код для strlen и strcpy. Например, strlen может выглядеть примерно так: "int strlen (char * x) {char y = x; while ( (y ++)); return (yx) -1;}"

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

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

Когда вы разбираете вещи в математике, вы попадаете на отдельные части, которые дети могут понять. Большинство людей доверяют математике; хотя бы базовая арифметика (или, как минимум, подсчет).

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

Я говорил с некоторыми программистами из колледжа или недавними выпускниками, которые прямо возражают против идеи, что код без ошибок может быть написан. Они списали такую ​​возможность, и хотя они признают, что некоторые впечатляющие примеры (которые мне удалось показать) являются убедительными аргументами, они считают такие образцы непредставительными редкими случайностями и все же отвергают возможность подсчета на наличие таких более высоких стандартов. (Гораздо, совсем другое отношение, чем гораздо более надежное основание, которое мы видим в математике.)


1
В то время как вы делаете хороший аргумент в пользу сложности программирования, вы почти не учитываете математику! На самом деле, вы, кажется, недооцениваете сложность формальной математики: «Когда вы разбираете вещи в математике, вы попадаете на отдельные части, которые дети могут понять», правда ? Кроме того, то же самое можно сказать о достаточно «высокоуровневом» программировании (например, Scratch предназначен для детей). Также обратите внимание, что, хотя полная C-спецификация не реализуема, компилятор, поддерживающий важное подмножество, был формально корректен с помощью компьютерных доказательств.
Дискретная ящерица

2+3=5

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

Дискретная ящерица - это компьютерная наука SE. Более того, прочитав другие ответы до того, как я написал, я почувствовал, что они касаются математики гораздо больше, чем компьютеров. Я чувствовал, что мой ответ был лучше, не делая его длиннее, просто добавив слова, которые в значительной степени были бы излишними с тем, что было написано в другом месте. /// Что касается Scratch, высокий уровень сложнее, а не проще (если смотреть на перспективу полного понимания всех движущихся частей). С этой точки зрения, с которой я писал, сборка проще, чем Scratch поверх других слоев (с электронными воротами NAND еще проще)
TOOGAM

0

Математические доказательства описывают, «что» знания, и программы описывают, как «знания».

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

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

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


2
Я бы сказал, что математические доказательства полностью способны описать знание «что»: возьмите, например, любое доказательство, которое создает пример для доказательства существования, или метод для вычисления значения. Тем не менее, я согласен с тем, что в доказательствах отсутствует что-либо, в том смысле, что нет другого состояния, кроме того, которое явно описано автором (или читателем!). Именно это состояние позволяет программе делать то, о чем не знает читатель / автор, а это невозможно при доказательстве. (конечно, у доказательств могут быть непреднамеренные особенности или результаты, но для их получения все еще требуется активная мысль)
Дискретная ящерица

@Discretelizard Это полезный комментарий. Я думаю, что грань между «что» и «как», безусловно, размыта. Доказательство того, что алгоритм делает то, что, как вы думаете, оно делает, на самом деле не описывает «как» в моем уме, а просто гарантирует сохранение определенных свойств. С философской точки зрения, я думаю, что «как» знание требует соответствия с миром. Программы всегда делают то, что им говорят. Когда у вас есть ошибка, то, что вы ей сказали, не соответствует миру (то, что вы моделируете). Математика, независимая от приложения (например, физические проблемы), кажется, все зависит от согласованности.
Джастин Майнерс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.