Есть много исследований в этой области ... как уже говорили другие, конструкции внутри языка программы являются сложными, и это только усугубляется, когда пытаются подтвердить или доказать для любого заданного ввода.
Однако многие языки допускают спецификации, какие входные данные являются приемлемыми (предварительные условия), а также позволяют указывать конечный результат (почтовые условия).
К таким языкам относятся: B, Event B, Ada, fortran.
И, конечно, есть много инструментов, которые призваны помочь нам доказать определенные свойства программ. Например, чтобы доказать свободу тупиков, можно было бы перехватить их программу через SPIN.
Есть также много инструментов, которые также помогают нам обнаруживать логические ошибки. Это можно сделать с помощью статического анализа (goanna, satabs) или фактического выполнения кода (gnu valgrind?).
Тем не менее, не существует единственного инструмента, который действительно позволил бы доказать всю программу, начиная с ее создания (спецификации), реализации и развертывания. Метод B подходит близко, но проверка его реализации очень и очень слабая. (Предполагается, что люди непогрешимы в переводе speicficaiton на имплентацию).
В качестве примечания, при использовании метода B вы часто обнаруживаете, что строите сложные доказательства из меньших аксиом. (То же самое относится и к другим доказательным доказательствам теорем).