flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Разрыв между «доказано» и «правильно» — это спецификация

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

Отсюда следуют все честные ограничения формальных методов:

seL4 — верифицированное микроядро, и оно опирается на явный список допущений: железо, DMA, компилятор.

Теперь это не рассуждение, а наблюдение на своей функции. Замер 16 августа (docs/benchmark-proof-cost-2.md) поймал разрыв в дереве flang. Ведомость печатает про «Чётное» из flang/stdlib/numbers.flang:

постусловие «чётность есть делимость на два» — доказано сведением цели с телом
функции … утверждение обо ВСЕХ входах, а не о написанных

А прогон той же функции на том же дереве:

$ flang run flang/stdlib/numbers.flang --function 'Чётное' --args '{"число": -4}'
{"result":false}

Противоречия нет, и в этом вся суть: «Чётное» и «Делится на» ошибаются одинаково (обе на -0, см. minus-zero-is-a-class), и «доказано» здесь значит ровно «две ошибки согласованы обо всех входах». Спецификация была написана через вторую функцию, а не независимо, — и доказательство честно проверило именно то, что ему дали.

Почему это важно записать. Это единственная причина, по которой формальные методы за пятьдесят лет не захватили индустрию. Популярные рассказы о доказуемых языках упоминают её вскользь, а потом строят на противоположном все обещания — см. what-the-popular-stories-get-wrong.

И обратная сторона того же, найденная замером 16 августа. «Не доказано» тоже не равно «ядро слабое». Замер цены доказательства записал у функции «Противоположное»: «содержательное утверждение (результат плюс х) равен 0 ядро не взяло». Ядро право: числа flang — IEEE-754, и при х = +∞ выходит (0 − ∞) + ∞ = не число, а «не число» нулю не равно. То же на −∞ и на самом «не число». Проверено прогоном.

То есть недоказуемость была свойством УТВЕРЖДЕНИЯ, а не ядра, — и приписать её ядру значило бы завести работу, которой не нужно. Правило отсюда простое: прежде чем чинить ядро под недоказанное утверждение, прогоните утверждение на враждебной выборке (±0, ±∞, не число, пустая строка).

Связано: goal-of-the-language, condition-for-the-revolution, minus-zero-is-a-class, bottleneck-moved-to-claim-shape