Есть ли доказуемые языки реального мира? (Scala?) - PullRequest
50 голосов
/ 31 октября 2010

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

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

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

Я слышал интересные вещи о тестируемости функциональных языков, таких как scala.

Как программное обеспечение инженеры какие варианты у нас есть?

Ответы [ 11 ]

35 голосов
/ 01 ноября 2010

Да, существуют языки, предназначенные для написания корректно корректного программного обеспечения. Некоторые даже используются в промышленности. Spark Ada , пожалуй, самый яркий пример. Я разговаривал с несколькими людьми из Praxis Critical Systems Limited, которые использовали его для кода, работающего на Boings (для мониторинга двигателя), и это кажется довольно хорошим. (Вот отличное краткое изложение / описание языка .) Этот язык и сопровождающая система доказательства используют второй метод, описанный ниже. Он даже не поддерживает динамическое выделение памяти!


У меня сложилось впечатление, что существует два метода написания правильного программного обеспечения:

  • Метод 1: Напишите программное обеспечение на языке, который вам удобен (например, C, C ++ или Java). Возьмите формальную спецификацию такого языка и докажите, что ваша программа верна.

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

  • Техника 2: Напишите программное обеспечение на несколько более неуклюжем языке (например, в некотором подмножестве Ada или измененной версии OCaml) и напишите доказательство правильности. Здесь программирование и доказательство идут рука об руку. Программирование в Coq даже полностью приравнивает их! (См. переписка Карри-Говарда )

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

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

Вот еще несколько примеров формальных подходов. Если это «реальный мир» или нет, зависит от того, кого вы спрашиваете: -)

Мне известен только один "достоверно корректный" язык веб-приложений : UR . Ur-программа, которая «проходит через компилятор», гарантированно не будет:

  • Страдают от любых видов атак с использованием кода
  • Вернуть неверный HTML
  • Содержит мертвые ссылки внутри приложения
  • Имеются несоответствия между формами HTML и полями, ожидаемыми их обработчиками
  • Включите код на стороне клиента, который делает неверные предположения о службах стиля "AJAX", которые предоставляет удаленный веб-сервер
  • Попытка неверных запросов SQL
  • Использование неправильного маршалинга или демаршалинга при связи с базами данных SQL или между браузерами и веб-серверами
23 голосов
/ 01 ноября 2010

Чтобы ответить на этот вопрос, вам действительно нужно определить, что вы подразумеваете под "доказуемым". Как указывал Рики, любой язык с системой типов - это язык со встроенной системой проверки, которая запускается каждый раз, когда вы компилируете свою программу. Эти системы доказательств почти всегда печально бессильны & mdash; отвечая на вопросы типа String против Int и избегая вопросов типа "список отсортирован?" & Mdash; но тем не менее они являются системами доказательств.

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

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

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

Несмотря на все это, стоит отметить, что система типов Scala (например, Haskell) является Turing Complete, что означает, что вы можете теоретически использовать ее для доказательства любого разрешимого свойства вашего кода, что вы написали свой код таким образом, что он поддается таким доказательствам. Haskell почти наверняка является лучшим языком для этого, чем Java (поскольку программирование на уровне типов в Haskell похоже на Prolog, тогда как программирование на уровне типов в Scala больше похоже на SML). Я не советую вам использовать системы типов Scala или Haskell таким образом (формальные доказательства алгоритмической корректности), но эта опция теоретически доступна.

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

10 голосов
/ 01 ноября 2010

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

  • Есть хорошо понятые языки с возможностью быть проверенными в использовании сегодня; Lisp через ACL2 один, и, конечно, у Scheme также есть хорошо понятное формальное определение.

  • ряд систем пытался использовать чисто функциональные языки или почти чистые, например, Haskell. В Haskell работает немало формальных методов.

  • На протяжении 20 с лишним лет существовала недолгая вещь для использования ручного доказательства формального языка, который затем был строго переведен на скомпилированный язык. Некоторыми примерами были IBM Cleanroom, ACL, Gypsy и Rose из Computational Logic, работа Джона МакХью и моей работы над надежной компиляцией C, и моя собственная работа над защитой от руки для программирования на C-системах. Все они привлекли некоторое внимание, но никто из них не реализовал это на практике.

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

10 голосов
/ 01 ноября 2010

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

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

4 голосов
/ 10 февраля 2011

Я участвую в двух доказуемых языках. Первый - это язык, поддерживаемый Perfect Developer, системой для определения sotfware, его доработки и генерации кода. Он использовался для некоторых больших систем, включая сам PD, и преподавался во многих университетах. Второй доказуемый язык, с которым я связан, - это доказуемое подмножество MISRA-C, см. C / C ++ Verification Blog , чтобы узнать больше.

4 голосов
/ 01 ноября 2010

Проверьте Омега .

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

4 голосов
/ 01 ноября 2010

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

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

4 голосов
/ 01 ноября 2010

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

Это - забавное чтение, если вам интересны функциональные языки программирования и чисто функциональные языки программирования.

3 голосов
/ 10 июня 2012

Мой (спорно) определение "реального мира" в контексте доказуемо-правильный код:

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

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

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

3 голосов
/ 01 ноября 2010

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

EDIT ===== Убрал мои неверные представления о том, что ML «доказуем».

...