Я не в состоянии сказать , сколько еще исследование должно быть сделано по этой теме, но я могу сказать вам , что это исследование делается, например, Verisoft XT программа финансируется правительством Германии.
Концепции, которые, я думаю, вы ищете, называются формальной верификацией и программированием на основе контрактов , где последний является удобным для программиста способом сделать первый. В программировании на основе контрактов вы сначала пишете свой код как обычно, а затем вставляете в код так называемые контракты . Легко используемым языком, основанным на этой парадигме, является Spec # от Microsoft Research и функционально похожее, но немного менее симпатичное расширение Code Contracts для C #, которое вы оба можете попробовать онлайн (у них также есть аналогичные инструменты для других языков, см. Rise4fun) ). Упомянутый вами тип int с типом диапазона будет отражен двумя контрактами в функции:
Contract.Requires(-3 <= a && a <= 24);
Contract.Requires( 3 <= b && b <= 10);
Если вы хотите вызвать эту функцию, вам нужно будет использовать параметры, которые соответствуют этим критериям, или вы получите ошибку времени компиляции. Выше очень простые контракты, вы можете вставить практически любое предположение или требование о переменных или исключениях и их отношениях, о которых вы можете подумать, и компилятор проверит, покрывается ли каждое требование предположением или чем-то, что может быть обеспечено, т.е. из предположений. Вот почему, откуда исходит название: вызывающий абонент предъявляет требования , вызывающий обеспечивает их выполнение - как в деловом контракте.
Под капотом контракты кода обычно объединяются со знанием внутренней работы (операционной семантики) языка программирования в список условий проверки . Этот список представляет собой одно большое логическое предложение с свободными переменными - входами вашей программы. Если предложение верно для всех возможных назначений переменных, то программа считается правильной. Чтобы проверить, так ли это, SMT Proverп РP(x1,x2,...,xn)nPиспользуется. Со стороны CS, эти два являются критическими частями процесса - генерация условий проверки является сложной, а SMT является либо NP-полной, либо неразрешимой проблемой, в зависимости от рассматриваемых теорий. Существует даже соревнование для специалистов по SMT, так что, безусловно, есть некоторые исследования в этом направлении. Кроме того, существуют альтернативные подходы к использованию SMT для формальной проверки, такие как перечисление пространства состояний, проверка символьной модели, проверка ограниченной модели и многие другие, которые также исследуются, хотя SMT, на самом деле, в настоящее время является наиболее «современным» подходом.
Относительно границ общей идеи:
- Как указывалось ранее, доказательство правильности программы является сложной вычислительной проблемой, поэтому может оказаться возможным, что проверка времени компиляции программы с контрактами (или другой формой спецификации) займет действительно много времени или может быть даже невозможна. Применение эвристики, которая работает хорошо большую часть времени, - лучшее, что можно с этим сделать.
- Чем больше вы задаете о вашей программе, тем выше становится вероятность наличия ошибок в описании самого . Это может привести к ложным срабатываниям (проверка времени компиляции завершается неудачно, даже если все без ошибок) или к ложному впечатлению о безопасности, даже если в вашей программе все еще есть ошибки.
- Написание контрактов или спецификаций - действительно утомительная работа, и большинство программистов слишком ленивы, чтобы делать это. Попробуйте написать программу на C # везде с контрактными кодами, через некоторое время вы подумаете: «Да ладно, это действительно необходимо?». Вот почему формальная проверка обычно используется только для проектирования оборудования и систем, важных для безопасности, таких как программное обеспечение для управления самолетами или автомобилями.
Последнее, что стоит упомянуть и которое не совсем соответствует приведенному выше объяснению, - это поле, называемое «Теория неявной сложности», например, эта статья . Он нацелен на характеристику языков программирования, в которых каждая программа, которую вы можете написать, попадает в определенный класс сложности, например P. В таком языке каждая написанная вами программа автоматически «гарантированно» имеет полиномиальное время выполнения, которое можно «проверить» во время компиляции, просто компилируя программу. Однако я не знаю каких-либо практически применимых результатов этого исследования, но я также далек от того, чтобы быть экспертом.