Как упомянул Vilx, правильность программ (включая то, заканчиваются они или нет), как правило, неразрешима. Однако такие инструменты, как Z3, показывают, что соответствующие конкретные случаи все еще можно рассуждать, несмотря на общую неразрешимость проблемы.
Статические анализаторы обычно ищут "простые" проблемы (например, нулевые разыменования, выходы за границы, числовые переполнения), но сравнительно быстрые и требуют небольшого руководства пользователя (подумайте о руководстве в духе добавления аннотаций типа в ваш код).
Неисчерпывающий (и предвзятый) список ключевых слов для поиска: «статические анализаторы», «абстрактная интерпретация»; "facebook infer", "airbus absint", "juliasoft".
Верификаторы пытаются доказать гораздо более богатые свойства, в частности, функциональную корректность, например, «Эта реализация сортировки действительно сортирует мой массив (и больше ничего не делает, например, освобождает некоторую глобальную память или обновляет элемент, достижимый из массива)?» или "эта крипто-реализация действительно реализует крипто-протокол, который она обещает реализовать?" Это намного более сложная задача, и инструменты из этого направления исследований, как правило, довольно медленные, требуют опытных пользователей с опытом формальной проверки и значительного руководства пользователя.
Неисчерпывающий (и предвзятый) список ключевых слов для поиска: «проверка», «логика хора», «логика разделения»; "eth viper", "microsoft dafny", "kuleuven validast", "microsoft f *".
Другие формальные методы существуют, например, уточнение (или корректирование по построению), но с еще меньшей поддержкой инструмента и, насколько я знаю, признанием в отрасли.