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

Ветка если разворачивается в обе стороны и на второй ярус, а разбор списка — ни в какую

Ходовое знание было такое: даром берётся развёртка ПЕРВОЙ ветки если — условие обещания дословно повторяет условие тела в положительную сторону, — а второй ярус если не берётся. Замер на нынешнем двоичном (bootstrap/flang, ветка b/dokazat-9) показывает, что граница проходит не там: берутся ВСЕ ветви если, сколько бы ярусов ни было, если записать цель дизъюнкцией по условиям, стоящим на пути к ветви.

Тело если A то X иначе если B то Y иначе Z закрывается тремя обещаниями:

обеспечивает «первая» (не A) или (результат равен X)
обеспечивает «средняя» A или ((не B) или (результат равен Y))
обеспечивает «последняя» A или (B или (результат равен Z))

Ядро называет два разных правила и оба считает доказательством: «разбор случаев по внутреннему условию цели» — когда цель начинается с (не A); «разбор цели по условию» — когда с A. Условие обещания обязано повторять условие тела дословно; пусть п равно E перед если не мешает, если подставить E вместо п.

Тем же приёмом берётся ветвь разбора по варианту без полей: (не (шаг равен вариант «Первый»)) или (результат равен "первый") — доказано. Вариант с полями так не взять: имена полей в обещании не связаны.

Где стена. разбор по СПИСКУ (случай пусто / случай голова и хвост) не разворачивается ничем. Проверены обе записи условия — (не (беды равен пустой список)) и (не ((длина беды) равен 0)); обе дали дословно «объявлено, не доказано: ни теоремы, ни примеров».

Что ещё берётся даром (замерено там же, сверх известного списка):

Ловушка при этом. Тело не (текст содержит "СЛОВО") не берётся ни в одну сторону — ни (текст содержит "СЛОВО") или (не результат), ни обратное. А пара обещаний, которую всё-таки удаётся доказать про такую функцию, целиком переживает подмену тела на постоянное нет: обе половины — одна и та же импликация, записанная прямо и через противоположное. Доказано — и пусто.

Чем подтверждено. scripts/lsp-check.flang (18 обещаний, доказано 18) и fspec/forgery.flang (18 обещаний, доказано 18); четыре снятых обещания — ровно те, что упёрлись в разбор списка и в постоянный список записей.

Связано: three-of-five-named-postcondition-walls-are-already-gone