Я заметил, что мне гораздо проще записывать математические доказательства без ошибок, чем записывать компьютерную программу без ошибок.
Кажется, это нечто более распространенное, чем просто мой опыт. Большинство людей постоянно ошибаются в программном обеспечении, и у них есть компилятор, который постоянно сообщает им, в чем заключается ошибка. Я никогда не слышал о ком-то, кто написал большую компьютерную программу без ошибок в ней за один раз, и был полностью уверен, что она будет без ошибок. (На самом деле, вряд ли какие-либо программы без ошибок, даже многие из них отлажены).
Тем не менее, люди могут писать целые статьи или книги с математическими доказательствами без какого-либо компилятора, который когда-либо давал бы им обратную связь о том, что они допустили ошибку, а иногда даже без получения обратной связи от других.
Позвольте мне быть ясным. Нельзя сказать, что люди не делают ошибок в математических доказательствах, но даже для слегка опытных математиков ошибки обычно не так проблематичны и могут быть решены без помощи какого-либо «внешнего оракула», такого как компилятор, указывающий на ваш ошибка.
На самом деле, если бы это было не так, математика вряд ли была бы возможна, как мне кажется.
Таким образом, это заставило меня задать вопрос: что такого отличного в написании безошибочных математических доказательств и написании безошибочного компьютерного кода, что делает так, чтобы первое было гораздо более податливым, чем второе?
Можно сказать, что просто тот факт, что у людей есть «внешний оракул» компилятора, указывающий им на их ошибки, делает программистов ленивыми, мешая им делать то, что необходимо для строгого написания кода. Эта точка зрения будет означать, что если бы у них не было компилятора, они могли бы быть такими же безошибочными, как математики.
Это может показаться вам убедительным, но, основываясь на моем опыте программирования и написания математических доказательств, мне интуитивно кажется, что это действительно не объяснение. Кажется, в этих двух начинаниях есть что-то более принципиальное.
Моя первоначальная мысль заключается в том, что в чем может быть разница, так это в том, что для математика правильное доказательство требует только каждого логического шага, чтобы быть правильным. Если каждый шаг верен, все доказательство верно. С другой стороны, для того, чтобы программа не содержала ошибок, не только каждая строка кода должна быть правильной, но и ее отношение к любой другой строке кода в программе.
Другими словами, если шаг в доказательстве верен, то ошибка в шаге никогда не испортит шагНо если строка кода записана правильно, то ошибка в строке повлияет на работу строки , так что всякий раз, когда мы пишем строку мы должны учитывать ее отношение ко всем другим строкам. Мы можем использовать инкапсуляцию и все такое, чтобы ограничить это, но это не может быть полностью удалено.Y X X Y X X
Это означает, что процедура проверки на ошибки в математическом доказательстве по существу линейна по количеству этапов доказательства, но процедура проверки на ошибки в компьютерном коде по существу экспоненциальна по количеству строк кода.
Как вы думаете?
Примечание. Этот вопрос содержит большое количество ответов, в которых рассматриваются различные факты и точки зрения. Прежде чем ответить, прочитайте их все и отвечайте, только если у вас есть что добавить. Избыточные ответы или ответы, не основанные на фактах, могут быть удалены.
Ответы:
Позвольте мне предложить одну причину и одно заблуждение в качестве ответа на ваш вопрос.
Основная причина , что проще писать ( по- видимому) правильные математические доказательства, что они написаны на очень высоком уровне. Предположим, что вы можете написать такую программу:
Было бы намного сложнее ошибиться при программировании таким образом, поскольку спецификация программы гораздо более краткая, чем ее реализация . Действительно, каждый программист, который пытается преобразовать псевдокод в код, особенно в эффективный код, сталкивается с этой большой пропастью между идеей алгоритма и деталями его реализации . Математические доказательства концентрируются больше на идеях, а не на деталях.
Настоящим аналогом кода для математических доказательств являются компьютерные доказательства . Их гораздо сложнее разработать, чем обычные текстовые доказательства, и часто можно обнаружить различные скрытые углы, которые «очевидны» для читателя (который обычно даже не замечает их), но не так очевидны для компьютера. Кроме того, поскольку в настоящее время компьютер может заполнять только относительно небольшие пробелы, доказательства должны разрабатываться до такого уровня, чтобы читающий их человек пропустил бы лес за деревьями.
Важным заблуждением является то, что математические доказательства часто верны. На самом деле, это, вероятно, довольно оптимистично. Очень сложно писать сложные доказательства без ошибок, а статьи часто содержат ошибки. Пожалуй, наиболее известные недавние случаи - это первая попытка Уайлза (частный случай) теоремы модульности (которая подразумевает последнюю теорему Ферма), а также различные пробелы в классификации конечных простых групп, включая более 1000 страниц на квазитиновых группах, которые были написано через 20 лет после того, как классификация была якобы закончена.
Ошибка в работе Воеводскима сделала его сомнение , письменные доказательств настолько, что он начал развивать теорию типа Гомотопического , логическую основу полезную для разработки гомотопической теории формально, и в дальнейшем использовал компьютер , чтобы проверить , все его последующие работы (по крайней мере , по его собственному прием). Несмотря на то, что это крайняя (и в настоящее время непрактичная) позиция, тем не менее, при использовании результата следует просмотреть доказательство и проверить, верно ли оно. В моем районе есть несколько статей, о которых известно, что они ошибочны, но никогда не были отозваны, чей статус передается из уст в уста среди экспертов.
источник
(Я, вероятно, рискую несколькими отрицательными отзывами здесь, поскольку у меня нет времени / интереса, чтобы сделать это правильным ответом, но я нахожу приведенный ниже текст (и остальную часть цитируемой статьи) весьма проницательным, также учитывая, что они написаны от известного математика. Возможно, я смогу улучшить ответ позже.)
Идея, которая, как я полагаю, не особенно отличается от существующего ответа, заключается в том, что «доказательство» или аргумент сообщается математическому сообществу, цель которого состоит в том, чтобы убедить их в том, что (утомительные) детали могут быть заполнены, в принципе, получить полностью определенное формальное доказательство - не делая этого вообще. Одним из важных примеров этого является то, что вы можете использовать существующие теоремы, просто указав их, но повторное использование кода в целом гораздо сложнее. Также рассмотрим незначительные «ошибки», которые могут полностью сделать часть кода бесполезной (например, это SEGFAULT), но могут оставить математический аргумент в значительной степени нетронутым (то есть, если ошибка может содержаться без свертывания аргумента).
ДОКАЗАТЕЛЬСТВО И ПРОГРЕСС В МАТЕМАТИКЕ (с. 9-10), УИЛЬЯМ П. ТЕРСТОН https://arxiv.org/pdf/math/9404236.pdf
источник
(void*)1
иopen('/dev/null')
, которые могут даже не быть переносимыми между различными субкультурами, не говоря уже о переводе на язык назначения. (Читатель просто должен уловить их приблизительную семантику благодаря многолетнему опыту.) Я думаю, что математические доказательства содержат меньше такого «сленга». Если доказательство использует слово, его фактический универсальный смысл должен быть выводимым читателем как - то. Компьютерные программы даже не имеют универсального значения!Позвольте мне начать с цитирования EW Dijkstra:
Хотя то, что Дейкстра имел в виду под «программированием», немного отличается от текущего использования, в этой цитате все же есть некоторые достоинства. В других ответах уже упоминалось, что уровень абстракции в математике может быть намного выше, чем в программировании, что означает, что мы можем игнорировать некоторые хитрые части, если мы хотим это сделать.
Тем не менее, я считаю, что это всего лишь следствие более фундаментального различия между доказательством и компьютерной программой, которая является их целью .
Основной целью математического доказательства является, среди прочего, убедить себя в том, что математическое утверждение является правильным и, возможно, даже более важным, достижение понимания . Следовательно, вы можете выбрать работу только в математическом мире, где все создано так, что понимание может быть достигнуто путем замысла (хотя некоторые студенты просят отличаться ...) Это именно то, что Дейкстра имел в виду под «чистыми математиками», теми, кто (почти) занимаются только математическими фактами и пониманием их свойств.
Таким образом, вы не должны удивляться, что правильные доказательства являются относительно безошибочными: это и есть смысл всего «упражнения». (Тем не менее, это не значит, что ошибок не существует или их просто не существует, чтобы ошибаться, говорят только люди)
Теперь, если мы рассмотрим программирование, какова наша цель? Мы на самом деле не ищем понимания, мы хотим что-то, что работает . Но когда что-то "работает"? Что-то работает, когда мы успешно создали что-то, что позволяет какой-то странной машине выполнить задачу, которую мы хотим, и желательно тоже довольно быстро.
Это, я считаю, фундаментальное различие, поскольку это означает, что наша цель не может быть просто сформулирована как некая теорема, которую «доказывает» наша программа, мы хотим чего-то в реальном мире (что бы это ни было), а не какой-то математический артефакт. Это означает, что мы не можем чисто теоретически достичь нашей цели (хотя Дейкстра попросит вас попробовать ее безотносительно), так как мы должны умиротворить машину, надеяться, что мы действительно знаем, какую задачу мы хотим выполнить, а также знаем о вещах, которые не рассматривались, но все же происходят как - то.
Итак, в конце концов, нет другого пути, кроме как просто попробовать и, возможно, потерпеть неудачу, исправить, потерпеть неудачу и повторить попытку, пока мы не будем несколько удовлетворены результатом.
Обратите внимание, что ваша гипотеза написания безошибочных доказательств проще, чем безошибочные программы (которые на самом деле являются разными утверждениями, как указывает @Ariel ), на самом деле может быть неверной, поскольку доказательства часто создаются методом проб и ошибок на каком-то уровне. Тем не менее, я надеюсь, что это проливает некоторый свет на вопрос, который подразумевается: «В чем на самом деле разница между доказательством некоторой теоремы и написанием программы?» (На что неосторожный наблюдатель переписки Карри-Говарда может сказать: «Ничего!»)
Как упомянуто в комментариях @wvxvw, следующие параграфы «заметок по структурированному программированию» (EWD249, стр. 21) очень актуальны:
источник
Лампорт дает основания для разногласий по поводу распространенности ошибок в доказательствах в разделе Как написать доказательство (стр. 8-9) :
источник
Одно большое отличие состоит в том, что программы, как правило, написаны для работы с входными данными, тогда как математические доказательства обычно начинаются с набора аксиом и ранее известных теорем. Иногда вам нужно охватить несколько угловых случаев, чтобы получить достаточно общее доказательство, но случаи и их разрешение явно перечислены, а область действия результата неявно ограничена рассматриваемыми случаями.
Сравните это с компьютерной программой, которая должна обеспечить «правильный» вывод для диапазона возможных входов. Редко можно перечислить все входные данные и попробовать их все. Что еще хуже, предположим, что программа взаимодействует с человеком и позволяет их вкладу изменять функционирование? Люди, как известно, непредсказуемы, и число возможных вкладов в достаточно большую программу взаимодействия с людьми растет невероятными темпами. Вы должны попытаться предвидеть все различные способы использования программы и попытаться заставить все эти варианты использования либо работать, либо, по крайней мере, терпеть неудачу разумным образом, когда отказ является единственным вариантом. И это при условии, что вы даже знаете, как это должно работать во всех этих непонятных угловых случаях.
Наконец, большую программу нельзя сравнивать ни с одним доказательством, даже со сложным. Большая программа, вероятно, больше похожа на сбор и просмотр небольшой библиотеки литературы, в некоторых из которых могут быть ошибки, с которыми вам нужно работать. Для программ, более масштабируемых как единое доказательство, которое может представлять собой небольшую реализацию алгоритма, скажем, опытные инженеры-программисты могут выполнить их без ошибок, особенно при использовании современных инструментов, которые предотвращают / устраняют типичные тривиальные ошибки (например, орфографические ошибки). ), которые эквивалентны ранним проблемам, которые вы решите при корректуре.
источник
Они говорят, что проблема с компьютерами в том, что они делают именно то , что вы им говорите.
Я думаю, что это может быть одной из многих причин.
Обратите внимание, что с компьютерной программой писатель (вы) умный, а читатель (процессор) тупой.
Но с математическим доказательством писатель (вы) умен, а читатель (рецензент) также умен.
Это означает, что вы никогда не можете позволить себе попасть в «хорошо, вы понимаете, что я имею в виду » ситуацию с компьютером. Он делает именно то, что вы говорите, не зная ваших намерений.
Например, скажем, это шаг в каком-то доказательстве:
источник
-x
оно составное. Тот факт, что этот шаг неверен, когда-x = 3
очень важен для правильности завершенного доказательства!]Один из вопросов, который, я думаю, не был рассмотрен в ответе Ювала, заключается в том, что, кажется, вы сравниваете разных животных.
Проверка семантических свойств программ неразрешима (теорема Райса), и, аналогично, проверка, является ли утверждение в логике предикатов первого порядка истинным, также неразрешима. Дело в том, что нет реальной разницы в твердости от того, как вы смотрите на проблемы. С другой стороны, мы можем рассуждать о синтаксических свойствах программ (компиляторов), и это аналогично тому, что мы можем проверять доказательства. Ошибки (код не делает то, что я хочу) являются семантическими, поэтому вы должны сравнить их с их правильным аналогом.
Я укреплю Юваль и скажу, что целые поля выросли благодаря мотивации написания математических доказательств, которые могут быть записаны и проверены в некоторой формальной системе, поэтому даже процесс проверки вовсе не тривиален.
источник
Я считаю, что основными причинами являются идемпотентность (дает одинаковые результаты для тех же входных данных) и неизменность (не меняется).
Что если математическое доказательство может дать разные результаты, если оно было прочитано во вторник или когда год перешел к 2000 году с 1999 года? Что если часть математического доказательства состояла в том, чтобы вернуться на несколько страниц назад, переписать несколько строк, а затем начать заново с этого момента?
Я уверен, что такое доказательство будет почти так же подвержено ошибкам, как обычный сегмент компьютерного кода.
Я вижу и другие вторичные факторы:
источник
Я согласен с тем, что написал Ювал. Но есть и более простой ответ: на практике инженеры программного обеспечения, как правило, даже не пытаются проверить правильность своих программ, они просто не делают, они, как правило, даже не записывают условия, которые определяют, когда программа является правильной.
Для этого есть разные причины. Одна из них заключается в том, что большинство разработчиков программного обеспечения не имеют навыков для четкой математической формулировки задач и не умеют писать доказательства корректности.
Другое - определение условий корректности для сложной программной системы (особенно распределенной) - очень сложная и трудоемкая задача. Ожидается, что у них будет что-то, что, кажется, сработает в течение нескольких недель.
Другая причина заключается в том, что правильность программы зависит от многих других систем, написанных другими, которые также не имеют четкой семантики. Существует закон Хайрама, который, по сути, гласит, что если ваша библиотека / служба будет вести себя заметным образом (не входит в ее контракт), кто-то в конечном итоге будет зависеть от этого. По сути, это означает, что идея разработки программного обеспечения в модульной форме с четкими контрактами, такими как леммы в математике, не работает на практике. Это ухудшается в языках, в которых используется отражение. Даже если программа верна сегодня, она может сломаться завтра, когда кто-нибудь проведет какой-то тривиальный рефакторинг в одной из ее зависимостей.
На практике обычно происходит тестирование. Тесты действуют как то, что ожидается от программы. Каждый раз, когда обнаруживается новая ошибка, они добавляют тесты для ее обнаружения. Это работает в некоторой степени, но это не доказательство правильности.
Когда люди не имеют навыков определения правильности, написания правильных программ и не должны этого делать, и делать это довольно сложно, неудивительно, что программное обеспечение не является правильным.
Но учтите также, что в конце концов в лучших местах разработка программного обеспечения осуществляется путем анализа кода. То есть автор программы должен убедить хотя бы еще одного человека, что программа работает правильно. В этом и заключаются некоторые неофициальные аргументы высокого уровня. Но, как правило, ничего похожего на четкое строгое определение правильности или доказательство правильности не происходит.
В математике люди ориентированы на правильность. В разработке программного обеспечения есть много вещей, о которых должен заботиться программист, и между ними есть компромиссы. Наличие программного обеспечения без ошибок или даже хорошего определения правильности (с требованиями, изменяющимися со временем) является идеалом, но оно должно быть заменено другими факторами, и одним из наиболее важных среди них является время, потраченное на его разработку существующими Разработчики. Таким образом, на практике в лучших местах цель и процессы максимально снижают риск ошибок, а не делают программное обеспечение безошибочным.
источник
Уже есть много хороших ответов, но есть еще много причин, по которым математика и программирование не совпадают.
1 Математические доказательства, как правило, гораздо проще, чем компьютерные программы. Рассмотрим первые шаги гипотетического доказательства:
Пока доказательство в порядке. Давайте превратим это в первые шаги аналогичной программы:
У нас уже есть множество проблем. Предполагая, что пользователь действительно ввел целое число, мы должны проверить границы. Является ли больше , чем -32768 (или что - то минимальное ИНТ на вашей системе)? Является менее чем 32767? Теперь мы должны проверить то же самое для б . И поскольку мы добавили a и b, программа не верна, если только a + bбольше -32768 и меньше 32767. Это 5 отдельных условий, которые программист должен беспокоиться о том, что математик может игнорировать. Программист должен не только беспокоиться о них, он должен выяснить, что делать, если одно из этих условий не выполнено, и написать код, который он решит, как только он решит эти условия. Математика проста. Программирование сложно.
2 Спрашивающий не говорит, имеет ли он в виду ошибки времени компиляции или ошибки времени выполнения, но программистам, как правило, просто наплевать на ошибки времени компиляции. Компилятор находит их, и их легко исправить. Они как опечатки. Как часто люди вводят несколько абзацев без ошибок в первый раз?
3 Обучение.С самого раннего возраста нас учат математике, и мы снова и снова сталкиваемся с последствиями мелких ошибок. Обученный математик должен был начать решать многоэтапные задачи алгебры, обычно в средней школе, и делать десятки (или более) таких задач каждую неделю в течение года. Один упавший отрицательный знак вызвал ошибку всей проблемы. После алгебры проблемы становились все длиннее и сложнее. Программисты, с другой стороны, обычно проходят гораздо менее формальную подготовку. Многие самоучки (по крайней мере на начальном этапе) и не получили формального обучения до университета. Даже на университетском уровне программистам приходится посещать довольно много уроков по математике, в то время как математики, вероятно, посещали один или два урока программирования.
источник
Мне нравится ответ Ювала, но я хотел немного его отругать. Одна из причин, по которой вам может быть проще писать математические доказательства, может сводиться к тому, насколько платонической онтологии является математическая. Чтобы понять, что я имею в виду, подумайте о следующем:
Хотя можно спорить о том, облегчают ли вышеуказанные ограничения написание программы, я думаю, что существует широкое согласие о том, что вышеуказанные ограничения облегчают рассуждения о программе. Главное, что вы делаете при написании доказательства по математике, это рассуждение о том, что вы сейчас пишете (поскольку, в отличие от программирования, вам никогда не придется дублировать усилия в математике, поскольку абстракции бесплатны), поэтому обычно стоит настаивать на вышеуказанные ограничения.
источник
Фундаментальные математические доказательства не составляют приложения реального мира, разработанного для удовлетворения потребностей живых людей.
Люди будут менять свои желания, потребности и требования, что, возможно, ежедневно в сфере компьютерных программ.
С таким же ясным требованием, как и математическая задача, можно написать безошибочную программу. Доказательство того, что алгоритм Дейкстры может найти кратчайший путь между двумя точками на графе, - это не то же самое, что реализация программы, которая принимает произвольные входные данные и находит кратчайшие точки между любыми двумя точками в нем.
Есть проблемы с памятью, производительностью и аппаратным обеспечением для управления. Хотелось бы, чтобы мы не думали о тех, кто при написании алгоритмов, что мы могли бы использовать чистые и функциональные конструкции для управления этим, но компьютерные программы живут в «реальном» мире аппаратных средств, тогда как математическое доказательство находится в ... «теории».
Или, чтобы быть более кратким :
источник
Глядя на это с другой стороны, в неакадемических условиях это часто сводится к деньгам.
Как хорошо утверждают другие посты, Math является единственной абстрактной спецификацией, поэтому доказательство должно работать последовательно только в рамках этой спецификации, чтобы быть доказанным. Компьютерная программа может работать со многими реализациями абстрактной спецификации математики, то есть способ, которым один язык, или производитель оборудования, реализует математику с плавающей запятой, может немного отличаться от другого, что может вызвать небольшие колебания результатов.
Таким образом, «проверка» компьютерной программы перед ее написанием будет включать проверку логики на аппаратном уровне, уровне операционной системы, уровне драйвера, языке программирования, компиляторе, возможно, интерпретаторе и т. Д. Для каждой возможной комбинации аппаратных средств, которые программа возможно, будет запущен и любые мыслимые данные, которые он может проглотить. Вы, вероятно, найдете этот уровень подготовки и понимания в космических миссиях, системах вооружений или системах управления ядерной энергией, где провал означает десятки миллиардов потерянных долларов и потенциально много погибших, но не намного больше.
Для вашего «повседневного» программиста и / или бизнеса гораздо более экономически выгодно принять определенный уровень точности в основном правильного кода и продать продукт, который можно использовать, и разработчики могут задним числом исправлять ошибки, когда они обнаруживаются во время его работы. использование.
источник
Я думаю, что ваши рассуждения верны, но ваш вклад - нет. Математические доказательства просто не более отказоустойчивы, чем программы, если оба написаны людьми. Дейкстра уже цитировался здесь, но я предложу дополнительную цитату.
Это слегка отредактированные последние три абзаца из первой главы структурированного программирования Дейкстры.
Чтобы перефразировать это, лучше применить к вашему вопросу: правильность во многом зависит от размера вашего доказательства. Правильность длинных математических доказательств установить очень сложно (множество опубликованных «доказательств» живет в неопределенности, так как на самом деле их никто не проверял). Но если вы сравните правильность тривиальных программ с тривиальными доказательствами, вероятно, заметной разницы нет. Тем не менее, автоматизированные помощники по проверке (в более широком смысле ваш Java-компилятор также является помощником по проверке), позволяют программам побеждать, автоматизируя множество основ.
источник
Как и другие ответы, затронутые в их ответах (я хочу уточнить), но большая часть проблемы связана с использованием библиотеки. Даже с идеальной документацией (такой же распространенной, как и код без ошибок) невозможно передать полное знание библиотеки каждому программисту, использующему библиотеку. Если программист не совсем понимает свою библиотеку, он может ошибиться при ее использовании. Иногда это может привести к критическим ошибкам, которые обнаруживаются, когда код не работает. Но для незначительных ошибок они могут остаться незамеченными.
Подобная ситуация была бы, если бы математик использовал существующие доказательства и леммы, не понимая их полностью; их собственные доказательства, вероятно, будут ошибочными. Хотя это может означать, что решение состоит в том, чтобы полностью изучить каждую используемую библиотеку; это практически очень много времени и может потребовать знания предметной области, которой программист не имеет (я очень мало знаю о секвенировании ДНК / синтезе белка; но могу работать с этими понятиями, используя библиотеки).
Говоря более кратко, разработка программного обеспечения (на самом деле разработка в целом) основана на инкапсуляции различных уровней абстракции, чтобы позволить людям сосредоточиться на небольших областях проблемы, на которой они специализируются. Это позволяет людям приобретать опыт в своей области, но также требует отличного общения между каждым слоем. Когда это общение не идеально, оно вызывает проблемы.
источник
Я постараюсь быть оригинальным после всех этих замечательных ответов.
Программы являются доказательствами
Изоморфизм Карри-Говарда говорит нам, типы в программе являются теоремы и фактический код является их доказательство.
Следует признать, что это очень абстрактное и высокоуровневое мнение. Проблема, которую вы, вероятно, имеете в виду, заключается в том, что написание типичного кода сложнее, поскольку он становится слишком низкоуровневым. В большинстве случаев вам «нужно сказать машине, что делать». Или, чтобы посмотреть на это с другой стороны: математики действительно хороши в абстракции.
В качестве примечания: «Музыка потоков» - один из самых красивых мостов между ними. Это в основном создает вещи , чтобы быть в состоянии сказать : «Я хочу это в том , как» и машина магическим образом делает это именно так , как хотелось бы .
источник
Ни один из многих других ответов не указывает на следующее. Математические доказательства оперируют воображаемыми вычислительными системами, которые имеют бесконечную память и бесконечную вычислительную мощность. Поэтому они могут содержать произвольно большие числа с бесконечной точностью и не теряют точности при любых вычислениях.
источник
Это не. Математические доказательства по своей природе точно такие же глючные, просто их читатели более терпимы, чем компиляторы. Точно так же читатели компьютерной программы легко могут быть обмануты, полагая, что это правильно, по крайней мере до тех пор, пока они не попытаются запустить ее.
Например, если мы попытаемся перевести математическое доказательство на формальный язык, такой как ZFC, оно также будет содержать ошибки. Это потому, что эти доказательства могут быть очень длинными, поэтому мы вынуждены написать программу для их создания. Мало кто попадает в беду, на свой страх и риск, хотя ведутся активные исследования по оформлению основополагающих доказательств.
И действительно, математика может получить BSOD! Это был бы не первый раз!
Эта ортодоксальная идея о том, что все математические доказательства, которые были в достаточной степени проверены, являются по существу правильными или могут быть сделаны правильными, является одной и той же мотивацией для вашего программного проекта на работе: пока мы остаемся на дорожной карте, мы будем устранять все ошибки Функции завершены - это итеративный процесс, ведущий к определенному конечному продукту.
Вот обратная сторона. Послушайте, мы уже получили финансирование, утвердили бизнес-концепцию, все документы здесь, чтобы вы могли их прочитать. Нам просто нужно, чтобы вы казнили, и это точно!
Давайте не будем слишком жалеть Гильберта , он знал, во что ввязался. Это просто бизнес.
Если вы хотите быть по-настоящему уверенным, принимайте все на индивидуальной основе и делайте свои собственные выводы!
источник
Я вижу две важные причины, по которым программы более подвержены ошибкам, чем математические доказательства:
1: программы содержат переменные или динамические объекты, изменяющиеся со временем, тогда как математические объекты в доказательствах обычно являются статическими. Таким образом, нотация в математике может быть использована в качестве прямой поддержки рассуждений (и если a = b, это остается так), где это не работает в программах. Кроме того, эта проблема усугубляется, когда программы параллельны или имеют несколько потоков.
2: математика часто предполагает относительно аккуратно определенные объекты (графы, многообразия, кольца, группы и т. Д.), В то время как программирование имеет дело с очень грязными и довольно нерегулярными объектами: арифметикой конечной точности, конечными стеками, символьно-целочисленными преобразованиями, указателями, мусором, требующим сбора и т. д. Поэтому очень трудно учитывать совокупность условий, имеющих отношение к правильности.
источник
Вы должны различать две разные «категории»:
Мы использовали псевдокод в течение тысяч лет (например, алгоритм Евклида). Написание формального кода (на формальных языках, таких как C или Java) стало чрезвычайно популярным и полезным после изобретения компьютеров. Но, к сожалению, формальные доказательства (на официальных языках, таких как Principia Mathematica или Metamath) не очень популярны. И поскольку сегодня все пишут псевдо-доказательства, люди часто спорят о новых доказательствах. Ошибки в них можно обнаружить спустя годы, десятилетия или даже столетия после фактического «доказательства».
источник
Я не могу найти ссылку, но я думаю, что Тони Хоар однажды сказал что-то вроде следующего: Разница между проверкой программы и проверкой доказательства состоит в том, что доказательство может проверяться двумя строками одновременно.
Одним словом: местность.
Доказательства написаны так, чтобы их можно было легко проверить. Программы написаны так, что они могут быть выполнены. По этой причине программисты обычно пропускают информацию, которая будет полезна для тех, кто проверяет программу.
Рассмотрим эту программу, где х только для чтения
Это легко выполнить, но сложно проверить.
Но если я добавлю обратно в пропущенные утверждения, вы можете проверить программу локально, просто проверив, что каждая последовательность назначений верна в отношении ее пред- и постусловий и что для каждого цикла постусловие цикла подразумевается инвариант и отрицание петли охранника.
Возвращаясь к первоначальному вопросу: почему запись математических доказательств более надежна, чем написание компьютерного кода? Поскольку доказательства предназначены для того, чтобы их легко могли проверить их читатели, они легко проверяются их авторами и, таким образом, предупреждают авторов, как правило, не допускают (или, по крайней мере, сохраняют) логические ошибки в своих доказательствах. Когда мы программируем, мы часто не можем записать причину, по которой наш код верен; в результате как читателям, так и автору программы сложно проверить код; В результате авторы совершают (а затем сохраняют) ошибки.
Но есть надежда. Если, когда мы пишем программу, мы также записываем причину, по которой мы считаем, что программа правильная, тогда мы можем проверять код по мере его написания и, таким образом, писать менее ошибочный код. Это также дает то преимущество, что другие могут прочитать наш код и проверить его сами.
источник
Мы могли бы спросить, сложнее ли на практике или в принципе писать доказательства или писать код.
На практике доказательство намного сложнее, чем кодирование. Очень немногие люди, прошедшие два года обучения в колледже, могут написать доказательства, даже тривиальные. Среди людей, прошедших два года обучения на уровне колледжа, FizzBuzz может решить, по крайней мере, 30% .
Но в принципе есть фундаментальные причины, почему все наоборот. Доказательства, по крайней мере в принципе, могут быть проверены на правильность с помощью процесса, который не требует никакого суждения или понимания вообще. Программы не могут - мы даже не можем сказать, с помощью какого-либо предписанного процесса, остановится ли программа.
источник
Только небольшая часть математических утверждений, которые являются правдой, может быть практически доказана. Что еще более важно, было бы невозможно построить нетривиальный (*) набор математических аксиом, который позволил бы доказать все истинные утверждения. Если бы нужно было только писать программы для выполнения крошечной доли того, что можно было бы сделать с помощью компьютеров, можно было бы написать доказательственно правильное программное обеспечение, но к компьютерам часто обращаются с просьбой сделать что-то за пределами того, что доказуемо корректно. Программное обеспечение может выполнить.
(*) Можно определить набор аксиом, которые позволили бы перечислить все истинные утверждения и, таким образом, доказать, но в целом они не очень интересны. Хотя формально можно разделить наборы аксиом на те, которые являются или нет, условно говоря, нетривиальными, ключевой момент заключается в том, что доказуемое существование утверждений, которые являются правдивыми, но не могут быть доказаны, не является недостатком в наборе аксиом. Добавление аксиом, чтобы сделать любые существующие правдивые, но недоказуемые утверждения доказуемыми, заставило бы другие утверждения стать правдой, но без их доказуемости.
источник
Компьютерные программы проверены в реальном мире. Хитрая техническая ошибка в длинном математическом доказательстве, которую может понять только ограниченное число людей, имеет хороший шанс остаться незамеченной. Такая же ошибка в программном продукте может привести к странному поведению, которое замечают обычные пользователи. Таким образом, предпосылка может быть не правильной.
Компьютерные программы выполняют полезные функции реального мира. Они не должны быть на 100% правильными, чтобы сделать это, а высокие стандарты корректности довольно дороги. Доказательства полезны только в том случае, если они действительно что-то доказывают, поэтому пропуск «100% правильной» части не подходит для математиков.
Математические доказательства четко определены. Если доказательство неверно, автор допустил ошибку. Многие ошибки в компьютерных программах возникают из-за того, что требования не были должным образом сообщены, или существует проблема совместимости с тем, о чем программист никогда не слышал.
Многие компьютерные программы не могут быть подтверждены. Они могут решить неформально определенные проблемы, такие как распознавание лиц. Или они могут быть похожи на программное обеспечение для прогнозирования фондового рынка и имеют формально определенную цель, но содержат слишком много переменных реального мира.
источник
Значительная часть математики как деятельности человека заключалась в разработке предметно-ориентированных языков, на которых человеку легко проверять доказательства.
Качество доказательства обратно пропорционально его длине и сложности. Длина и сложность часто уменьшаются путем разработки хороших обозначений для описания имеющейся ситуации, относительно которой мы делаем заявление, наряду со вспомогательными понятиями, взаимодействующими в рамках конкретного рассматриваемого доказательства.
Это непростой процесс, и большинство доказательств, свидетелями которых стали люди, отстраненные от передовых исследований, оказываются в математических областях (таких как алгебра и анализ), которые имели сотни, если не тысячи, лет, в течение которых обозначения этого поля был усовершенствован до такой степени, что сам акт записи доказательств ощущается как легкий ветерок.
Однако, находясь на переднем крае исследований, особенно если вы работаете над проблемами, не относящимися к областям с устоявшимися или хорошо разработанными обозначениями, я бы поставил на то, что трудность даже написания правильного доказательства приближается к сложности написания правильной программы. Это может быть связано с тем, что вам также придется в то же время написать аналог проекта языка программирования, обучить свою нейронную сеть правильно компилировать, попробовать написать в этом доказательство, не хватает памяти, попытаться оптимизировать язык, итерируйте свой мозг, изучая язык, снова пишите доказательства и т. д.
Повторюсь, я думаю, что написание правильных доказательств может приблизить сложность написания правильных программ в определенных областях математики, но эти области обязательно молоды и недостаточно развиты, потому что само понятие прогресса в математике тесно связано с легкостью доказательства проверка.
Еще один способ выразить мысль, которую я хочу подчеркнуть, заключается в том, что как языки программирования, так и математика в конце концов спроектированы таким образом, чтобы можно было компилировать компьютерные программы и доказательства соответственно. Просто компиляция компьютерной программы выполняется на компьютере и обеспечивает синтаксическую корректность, которая обычно не имеет ничего общего с правильностью самой программы, тогда как «компиляция» доказательства выполняется человеком и обеспечивает синтаксическую корректность, которая аналогична правильность доказательства.
источник
Вы честно сравниваете здесь яблоки и апельсины. Безотказный и без ошибок не одно и то же.
Если программа сравнивает числа
2
и3
говорит, что2 is greater than 3
это может быть связано с ошибкой реализации:Программа по-прежнему без ошибок, хотя. Сравнивая два числа
a
иb
, он всегда сможет сказать вам,b
больше ли онa
. Это просто не то, что вы (программист) должны были попросить сделать компьютер.источник
а) Потому что компьютерные программы больше, чем математические доказательства
а.1) Я считаю, что при написании сложных компьютерных программ используется больше людей, чем при написании математических доказательств. Это означает, что погрешность выше.
б) Поскольку генеральные директора / акционеры больше заботятся о деньгах, чем об устранении мелких ошибок , тем временем вы (как разработчик) должны выполнять свои задачи, чтобы выполнить некоторые требования / сроки / демонстрации
в) Поскольку вы можете быть программистом без «глубоких» знаний в области компьютинга, то в математике это будет трудно сделать (я верю)
Дополнительно:
NASA:
https://www.fastcompany.com/28121/they-write-right-stuff
источник
Основные уровни:
Давайте посмотрим на вещи на самом простом и самом базовом уровне.По математике имеем:
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;}"
Однако типичные компьютерные программы намного длиннее. Кроме того, во многих современных программах используется другой код, который может быть подвергнут менее тщательному тестированию или даже с ошибками. Современные системы намного сложнее, чем то, что можно легко обдумать, за исключением того, что вручную отмахиваются от множества мелочей как «деталей, обрабатываемых более низкими уровнями».
Эта обязательная сложность и уверенность в работе со сложными и даже неправильными системами делает компьютерное программирование большим количеством оборудования для проверки, чем математика, где все сводится к гораздо более простым уровням.
Когда вы разбираете вещи в математике, вы попадаете на отдельные части, которые дети могут понять. Большинство людей доверяют математике; хотя бы базовая арифметика (или, как минимум, подсчет).
Когда вы действительно разбиваете компьютерное программирование, чтобы увидеть, что происходит под капотом, вы в конечном итоге получаете сломанные реализации нарушенных стандартов и код, который в конечном итоге выполняется электронным способом, и эта физическая реализация находится всего на один шаг ниже микрокода, который делают большинство компьютерных специалистов, обучающихся в университете. не смей трогать (если они даже знают об этом).
Я говорил с некоторыми программистами из колледжа или недавними выпускниками, которые прямо возражают против идеи, что код без ошибок может быть написан. Они списали такую возможность, и хотя они признают, что некоторые впечатляющие примеры (которые мне удалось показать) являются убедительными аргументами, они считают такие образцы непредставительными редкими случайностями и все же отвергают возможность подсчета на наличие таких более высоких стандартов. (Гораздо, совсем другое отношение, чем гораздо более надежное основание, которое мы видим в математике.)
источник
Математические доказательства описывают, «что» знания, и программы описывают, как «знания».
Написание программ сложнее, потому что программист должен обдумать все возможные состояния и то, как в результате изменяется поведение программы. Доказательства используют формальные или категориальные рассуждения, чтобы доказать вещи о других определениях.
Большинство ошибок вызвано процессами, входящими в состояния, которые программист не ожидал. В программе у вас обычно есть тысячи или, в большой системе, миллионы возможных переменных, которые не являются статическими данными, но фактически преобразуют способ выполнения программы. Все это, взаимодействуя друг с другом, создает поведение, которое невозможно предвидеть, особенно в современном компьютере, где под вами меняются слои абстракции.
В доказательстве нет изменения состояния. Определения и объекты обсуждения являются фиксированными. Доказательство требует обдумывания проблемы в целом и рассмотрения множества случаев, но эти случаи фиксируются определениями.
источник