Если вы хотите уменьшить проблему до более общей проблемы, вы можете преобразовать код
<code>
if ((a < 5) && b > 10) {
// Do something
} else if ((a >= 5) && (b > 10)){
// handled else condition
} else if((a < 5) && (b <= 10)) {
// handled else condition
}
в
<code>
if ((a < 5) && b > 10) {
// Do something
} else if ((a >= 5) && (b > 10)){
// handled else condition
} else if((a < 5) && (b <= 10)) {
// handled else condition
} else {
/*@ assert false ; */
}
Разумный компилятор будет выдавать тот же код для преобразованной версии, что и для исходной версии, и теперь вы можете использовать статический анализ или генерацию тестов для проверки того, что assert
выполняется, что аналогично проверке того, что последний else
никогда не берется, и это именно то, что вас интересует.
Инструменты существуют, если приведенный выше код является Java (assert может быть аннотацией JML), C (assert может быть аннотацией ACSL) или C # (assert может быть аннотацией Spec #). Алгоритм Элиана Эббинга хорош, но я предлагаю вариант, чтобы автоматические средства проверки теорем, используемые в качестве серверной части для этих инструментов, выполняли свою работу без повторной реализации колеса, которое определяет, является ли данное логическое предложение тавтологией. Скорее всего, существующие колеса работают лучше, чем когда-либо.
Пример на C, с использованием Frama-C и Jessie:
int a, b;
main(){
if ((a < 5) && b > 10) {
// Do something
} else if ((a >= 5) && (b > 10)){
// handled else condition
} else if((a < 5) && (b <= 10)) {
// handled else condition
} else {
/*@ assert \false ; */
}
}
Утверждение не подтверждено, что указывает на то, что Джесси не смогла проверить, что последний случай был недоступен. При добавлении } else if ((a >= 5) && (b <= 10)) {
утверждение подтверждается.